From da4f2b8c2f1810528cac4001aa9f97b3a2c30326 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Fri, 30 Mar 2018 15:34:00 -0300 Subject: [PATCH 001/152] Fix zoom in unresponsive in radar mode --- scripts/system/+android/radar.js | 47 +++++++++++++++++--------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/scripts/system/+android/radar.js b/scripts/system/+android/radar.js index 455299dd5f..2b87f8955d 100644 --- a/scripts/system/+android/radar.js +++ b/scripts/system/+android/radar.js @@ -21,7 +21,7 @@ function printd(str) { } var radar = false; -var radarHeight = 10; // camera position meters above the avatar +var radarHeight = MyAvatar.position.y + 10; // camera position (absolute y) var tablet; var RADAR_CAMERA_OFFSET = -1; // 1 meter below the avatar @@ -46,11 +46,11 @@ var uniqueColor; function moveTo(position) { if (radar) { MyAvatar.position = position; - Camera.position = Vec3.sum(MyAvatar.position, { - x : 0, + Camera.position = { + x : MyAvatar.position.x, y : radarHeight, - z : 0 - }); + z : MyAvatar.position.z + }; } } @@ -386,12 +386,12 @@ function pinchUpdate(event) { radarHeight -= pinchIncrement; } } - var deltaHeight = avatarY + radarHeight - Camera.position.y; - Camera.position = Vec3.sum(Camera.position, { - x : 0, - y : deltaHeight, - z : 0 - }); + Camera.position = { + x: Camera.position.x, + y:radarHeight, + z:Camera.position.z + }; + if (!draggingCamera) { startedDraggingCamera = true; draggingCamera = true; @@ -401,7 +401,8 @@ function pinchUpdate(event) { } function isInsideSquare(coords0, coords1, halfside) { - return Math.abs(coords0.x - coords1.x) <= halfside + return coords0 != undefined && coords1!= undefined && + Math.abs(coords0.x - coords1.x) <= halfside && Math.abs(coords0.y - coords1.y) <= halfside; } @@ -412,7 +413,7 @@ function dragScrollUpdate(event) { // drag management var pickRay = Camera.computePickRay(event.x, event.y); var dragAt = Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, - radarHeight)); + radarHeight-MyAvatar.position.y)); if (lastDragAt === undefined || lastDragAt === null) { lastDragAt = dragAt; @@ -722,7 +723,7 @@ function Teleporter() { return { dragTeleportBegin : function(event) { printd("[newTeleport] TELEPORT began"); - var overlayDimensions = entityIconModelDimensions(); + var overlayDimensions = entityIconModelDimensions(MyAvatar.position.y); // var destination = computeDestination(event, MyAvatar.position, // Camera.position, radarHeight); // Dimension teleport and cancel overlays (not show them yet) @@ -843,7 +844,7 @@ var avatarIconDimensionsVal = { }; function avatarIconPlaneDimensions() { // given the current height, give a size - var xy = -0.003531 * radarHeight + 0.1; + var xy = -0.003531 * (radarHeight - MyAvatar.position.y) + 0.1; avatarIconDimensionsVal.x = Math.abs(xy); avatarIconDimensionsVal.y = Math.abs(xy); // reuse object @@ -1165,9 +1166,10 @@ var entityIconModelDimensionsVal = { y : 0.00001, z : 0 }; -function entityIconModelDimensions() { +function entityIconModelDimensions(y) { // given the current height, give a size - var xz = -0.002831 * radarHeight + 0.1; + // TODO: receive entity.position.y and substract to radarHeight + var xz = -0.002831 * (radarHeight - y) + 0.1; entityIconModelDimensionsVal.x = xz; entityIconModelDimensionsVal.z = xz; // reuse object @@ -1177,8 +1179,8 @@ function entityIconModelDimensions() { * entityIconPlaneDimensions: similar to entityIconModelDimensions but using xy * plane */ -function entityIconPlaneDimensions() { - var dim = entityIconModelDimensions(); +function entityIconPlaneDimensions(y) { + var dim = entityIconModelDimensions(y); var z = dim.z; dim.z = dim.y; dim.y = z; @@ -1255,15 +1257,15 @@ function hideAllEntitiesIcons() { function renderAllEntitiesIcons() { var entityPos; var entityProps; - var iconDimensions = entityIconModelDimensions(); - var planeDimensions = entityIconPlaneDimensions(); // plane overlays uses - // xy instead of xz + for ( var QUuid in entitiesData) { if (entitiesData.hasOwnProperty(QUuid)) { entityProps = Entities.getEntityProperties(QUuid, [ "position", "visible" ]); if (entityProps != null) { entityPos = entityProps.position; + var planeDimensions = entityIconPlaneDimensions(entityPos.y); // plane overlays uses + // xy instead of xz if (entitiesData[QUuid].icon != undefined && entityPos) { var iconPos = findLineToHeightIntersectionCoords( entityPos.x, @@ -1276,6 +1278,7 @@ function renderAllEntitiesIcons() { printd("entity icon pos bad for " + QUuid); continue; } + var iconDimensions = entityIconModelDimensions(entityPos.y); var dimensions = entitiesData[QUuid].planar ? planeDimensions : iconDimensions; Overlays.editOverlay(entitiesData[QUuid].icon, { From fc86525863df9eb5a2a01c948fa08f30e6cf616d Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 4 Apr 2018 12:00:06 +0200 Subject: [PATCH 002/152] Cleaned up a bit shadow map clear --- libraries/render-utils/src/RenderShadowTask.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 69c5b3c689..faa5889307 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -149,9 +149,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con batch.setStateScissorRect(viewport); batch.setFramebuffer(fbo); - batch.clearFramebuffer( - gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH, - vec4(vec3(1.0, 1.0, 1.0), 0.0), 1.0, 0, true); + batch.clearDepthFramebuffer(1.0, false); glm::mat4 projMat; Transform viewMat; From 36bc5f841627e170cb0d15c35586106d5c176eb5 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Thu, 5 Apr 2018 15:35:08 -0300 Subject: [PATCH 003/152] Fix the view snap when user starts zooming --- scripts/system/+android/radar.js | 37 ++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/scripts/system/+android/radar.js b/scripts/system/+android/radar.js index 2b87f8955d..120bec33c3 100644 --- a/scripts/system/+android/radar.js +++ b/scripts/system/+android/radar.js @@ -21,7 +21,8 @@ function printd(str) { } var radar = false; -var radarHeight = MyAvatar.position.y + 10; // camera position (absolute y) +var RADAR_HEIGHT_INIT_DELTA = 10; +var radarHeight = MyAvatar.position.y + RADAR_HEIGHT_INIT_DELTA; // camera position (absolute y) var tablet; var RADAR_CAMERA_OFFSET = -1; // 1 meter below the avatar @@ -386,6 +387,7 @@ function pinchUpdate(event) { radarHeight -= pinchIncrement; } } + Camera.position = { x: Camera.position.x, y:radarHeight, @@ -655,6 +657,7 @@ function Teleporter() { return; } + Camera.position = Vec3.sum(Camera.position, { x : xDelta, y : 0, @@ -1301,11 +1304,12 @@ function startRadar() { saveAllOthersAvatarsData(); Camera.mode = "independent"; - Camera.position = Vec3.sum(MyAvatar.position, { - x : 0, - y : radarHeight, - z : 0 - }); + Camera.position = { + x : MyAvatar.position.x, + y : radarHeight, + z : MyAvatar.position.z + }; + Camera.orientation = Quat.fromPitchYawRollDegrees(-90, 0, 0); radar = true; @@ -1394,15 +1398,25 @@ function connectRadarModeEvents() { Controller.keyPressEvent.connect(keyPressEvent); Controller.mousePressEvent.connect(mousePress); // single click/touch Controller.touchUpdateEvent.connect(touchUpdate); + Window.domainChanged.connect(domainChanged); MyAvatar.positionGoneTo.connect(positionGoneTo); } -function positionGoneTo() { - Camera.position = Vec3.sum(MyAvatar.position, { - x : 0, +function domainChanged() { + radarHeight = MyAvatar.position.y + RADAR_HEIGHT_INIT_DELTA; + Camera.position = { + x : MyAvatar.position.x, y : radarHeight, - z : 0 - }); + z : MyAvatar.position.z + }; +} + +function positionGoneTo() { + Camera.position = { + x : MyAvatar.position.x, + y : radarHeight, + z : MyAvatar.position.z + }; } function disconnectRadarModeEvents() { @@ -1411,6 +1425,7 @@ function disconnectRadarModeEvents() { Controller.mousePressEvent.disconnect(mousePress); Controller.touchUpdateEvent.disconnect(touchUpdate); MyAvatar.positionGoneTo.disconnect(positionGoneTo); + Window.domainChanged.disconnect(domainChanged); } function init() { From 573f399023eafd625212284f827ea3207f006f76 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Fri, 6 Apr 2018 14:45:16 +0200 Subject: [PATCH 004/152] Fixed incorrect shadow frustum far clip computation due to not taking into account shadow receivers --- .../render-utils/src/RenderShadowTask.cpp | 27 ++++++++++-------- libraries/render-utils/src/RenderShadowTask.h | 2 +- libraries/render/src/render/CullTask.cpp | 28 +++++++++++++------ libraries/render/src/render/CullTask.h | 2 +- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index faa5889307..fbb4bba263 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -230,12 +230,11 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende const auto queryResolution = setupOutput.getN(2); // Fetch and cull the items from the scene - // Enable models to not cast shadows (otherwise, models will always cast shadows) - static const auto shadowCasterFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask).withShadowCaster(); + static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask); - const auto fetchInput = FetchSpatialTree::Inputs(shadowCasterFilter, queryResolution).asVarying(); + const auto fetchInput = FetchSpatialTree::Inputs(shadowCasterReceiverFilter, queryResolution).asVarying(); const auto shadowSelection = task.addJob("FetchShadowTree", fetchInput); - const auto selectionInputs = FetchSpatialSelection::Inputs(shadowSelection, shadowCasterFilter).asVarying(); + const auto selectionInputs = FetchSpatialSelection::Inputs(shadowSelection, shadowCasterReceiverFilter).asVarying(); const auto shadowItems = task.addJob("FetchShadowSelection", selectionInputs); // Cull objects that are not visible in camera view. Hopefully the cull functor only performs LOD culling, not @@ -259,21 +258,22 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende char jobName[64]; sprintf(jobName, "ShadowCascadeSetup%d", i); const auto cascadeSetupOutput = task.addJob(jobName, i, _cullFunctor, tagBits, tagMask); - const auto shadowFilter = cascadeSetupOutput.getN(0); + const auto shadowRenderFilter = cascadeSetupOutput.getN(0); + const auto shadowBoundsFilter = cascadeSetupOutput.getN(1); auto antiFrustum = render::Varying(ViewFrustumPointer()); - cascadeFrustums[i] = cascadeSetupOutput.getN(1); + cascadeFrustums[i] = cascadeSetupOutput.getN(2); if (i > 1) { antiFrustum = cascadeFrustums[i - 2]; } // CPU jobs: finer grained culling - const auto cullInputs = CullShapeBounds::Inputs(sortedShapes, shadowFilter, antiFrustum).asVarying(); + const auto cullInputs = CullShapeBounds::Inputs(sortedShapes, shadowRenderFilter, shadowBoundsFilter, antiFrustum).asVarying(); const auto culledShadowItemsAndBounds = task.addJob("CullShadowCascade", cullInputs, shadowCullFunctor, RenderDetails::SHADOW); // GPU jobs: Render to shadow map sprintf(jobName, "RenderShadowMap%d", i); task.addJob(jobName, culledShadowItemsAndBounds, shapePlumber, i); - task.addJob("ShadowCascadeTeardown", shadowFilter); + task.addJob("ShadowCascadeTeardown", shadowRenderFilter); } task.addJob("ShadowTeardown", setupOutput); @@ -404,7 +404,11 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon const auto globalShadow = lightStage->getCurrentKeyShadow(); if (globalShadow && _cascadeIndexgetCascadeCount()) { - output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask).withShadowCaster(); + auto baseFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask); + // Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers) + output.edit1() = baseFilter; + // First item filter is to filter items to render in shadow map (so only keep casters) + output.edit0() = baseFilter.withShadowCaster(); // Set the keylight render args auto& cascade = globalShadow->getCascade(_cascadeIndex); @@ -417,10 +421,11 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon texelSize *= minTexelCount; _cullFunctor._minSquareSize = texelSize * texelSize; - output.edit1() = cascadeFrustum; + output.edit2() = cascadeFrustum; } else { output.edit0() = ItemFilter::Builder::nothing(); - output.edit1() = ViewFrustumPointer(); + output.edit1() = ItemFilter::Builder::nothing(); + output.edit2() = ViewFrustumPointer(); } } diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 98b70c0c9f..19ffcb4234 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -118,7 +118,7 @@ private: class RenderShadowCascadeSetup { public: - using Outputs = render::VaryingSet2; + using Outputs = render::VaryingSet3; using JobModel = render::Job::ModelO; RenderShadowCascadeSetup(unsigned int cascadeIndex, RenderShadowTask::CullFunctor& cullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) : diff --git a/libraries/render/src/render/CullTask.cpp b/libraries/render/src/render/CullTask.cpp index f04427540a..b5819f114f 100644 --- a/libraries/render/src/render/CullTask.cpp +++ b/libraries/render/src/render/CullTask.cpp @@ -368,17 +368,19 @@ void CullShapeBounds::run(const RenderContextPointer& renderContext, const Input RenderArgs* args = renderContext->args; const auto& inShapes = inputs.get0(); - const auto& filter = inputs.get1(); - const auto& antiFrustum = inputs.get2(); + const auto& cullFilter = inputs.get1(); + const auto& boundsFilter = inputs.get2(); + const auto& antiFrustum = inputs.get3(); auto& outShapes = outputs.edit0(); auto& outBounds = outputs.edit1(); outShapes.clear(); outBounds = AABox(); - if (!filter.selectsNothing()) { + if (!cullFilter.selectsNothing() || !boundsFilter.selectsNothing()) { auto& details = args->_details.edit(_detailType); Test test(_cullFunctor, args, details, antiFrustum); + auto scene = args->_scene; for (auto& inItems : inShapes) { auto key = inItems.first; @@ -393,16 +395,26 @@ void CullShapeBounds::run(const RenderContextPointer& renderContext, const Input if (antiFrustum == nullptr) { for (auto& item : inItems.second) { if (test.solidAngleTest(item.bound) && test.frustumTest(item.bound)) { - outItems->second.emplace_back(item); - outBounds += item.bound; + const auto shapeKey = scene->getItem(item.id).getKey(); + if (cullFilter.test(shapeKey)) { + outItems->second.emplace_back(item); + } + if (boundsFilter.test(shapeKey)) { + outBounds += item.bound; + } } } } else { for (auto& item : inItems.second) { if (test.solidAngleTest(item.bound) && test.frustumTest(item.bound) && test.antiFrustumTest(item.bound)) { - outItems->second.emplace_back(item); - outBounds += item.bound; - } + const auto shapeKey = scene->getItem(item.id).getKey(); + if (cullFilter.test(shapeKey)) { + outItems->second.emplace_back(item); + } + if (boundsFilter.test(shapeKey)) { + outBounds += item.bound; + } + } } } details._rendered += (int)outItems->second.size(); diff --git a/libraries/render/src/render/CullTask.h b/libraries/render/src/render/CullTask.h index 3c5a30de89..47abe8a960 100644 --- a/libraries/render/src/render/CullTask.h +++ b/libraries/render/src/render/CullTask.h @@ -110,7 +110,7 @@ namespace render { class CullShapeBounds { public: - using Inputs = render::VaryingSet3; + using Inputs = render::VaryingSet4; using Outputs = render::VaryingSet2; using JobModel = Job::ModelIO; From d5c252c9ad70cfb2e46c95b75cd3a71d7b8f5196 Mon Sep 17 00:00:00 2001 From: Cristian Duarte Date: Mon, 9 Apr 2018 16:24:03 -0300 Subject: [PATCH 005/152] Use MyAvatar.goToLocation in radar teleport. Use MyAvatar.goToLocation in radar teleport to prevent synchronization issues that make it fail occasionally when directly modifying its world position. It will work just as teleport.js does. --- scripts/system/+android/radar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/system/+android/radar.js b/scripts/system/+android/radar.js index 120bec33c3..8100cc0887 100644 --- a/scripts/system/+android/radar.js +++ b/scripts/system/+android/radar.js @@ -46,11 +46,11 @@ var uniqueColor; function moveTo(position) { if (radar) { - MyAvatar.position = position; + MyAvatar.goToLocation(position, false); Camera.position = { - x : MyAvatar.position.x, + x : position.x, y : radarHeight, - z : MyAvatar.position.z + z : position.z }; } } From 63e17e87b0fa4e00db8b871e731c34684a1f4f08 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Tue, 10 Apr 2018 19:21:23 -0300 Subject: [PATCH 006/152] Fix radar initial position. Clean radar.js --- scripts/system/+android/radar.js | 232 ++----------------------------- 1 file changed, 8 insertions(+), 224 deletions(-) diff --git a/scripts/system/+android/radar.js b/scripts/system/+android/radar.js index 8100cc0887..67ba896207 100644 --- a/scripts/system/+android/radar.js +++ b/scripts/system/+android/radar.js @@ -90,46 +90,6 @@ function keyPressEvent(event) { } } -function actionOnObjectFromEvent(event) { - var rayIntersection = findRayIntersection(Camera.computePickRay(event.x, - event.y)); - if (rayIntersection && rayIntersection.intersects - && rayIntersection.overlayID) { - printd("found overlayID touched " + rayIntersection.overlayID); - if (entitiesByOverlayID[rayIntersection.overlayID]) { - var entity = Entities.getEntityProperties( - entitiesByOverlayID[rayIntersection.overlayID], - [ "sourceUrl" ]); - App.openUrl(entity.sourceUrl); - return true; - } - } - if (rayIntersection && rayIntersection.intersects - && rayIntersection.entityID && rayIntersection.properties) { - printd("found " + rayIntersection.entityID + " of type " - + rayIntersection.properties.type); - if (rayIntersection.properties.type == "Web") { - printd("found web element to " - + rayIntersection.properties.sourceUrl); - App.openUrl(rayIntersection.properties.sourceUrl); - return true; - } - } - return false; -} - -function mousePress(event) { - mousePressOrTouchEnd(event); -} - -function mousePressOrTouchEnd(event) { - if (radar) { - if (actionOnObjectFromEvent(event)) { - return; - } - } -} - function toggleRadarMode() { if (radar) { endRadar(); @@ -230,9 +190,6 @@ function touchEnd(event) { if (analyzeDoubleTap(event)) return; // double tap detected, finish - if (radar) { - mousePressOrTouchEnd(event); - } } /** @@ -726,7 +683,7 @@ function Teleporter() { return { dragTeleportBegin : function(event) { printd("[newTeleport] TELEPORT began"); - var overlayDimensions = entityIconModelDimensions(MyAvatar.position.y); + var overlayDimensions = teleportIconModelDimensions(MyAvatar.position.y); // var destination = computeDestination(event, MyAvatar.position, // Camera.position, radarHeight); // Dimension teleport and cancel overlays (not show them yet) @@ -1125,39 +1082,10 @@ function renderAllOthersAvatarIcons() { } } -function entityAdded(entityID) { - printd("Entity added " + entityID); - var props = Entities.getEntityProperties(entityID, [ "type" ]); - printd("Entity added " + entityID + " PROPS " + JSON.stringify(props)); - if (props && props.type == "Web") { - printd("Entity Web added " + entityID); - saveEntityData(entityID, true); - } -} - -function entityRemoved(entityID) { - printd("Entity removed " + entityID); - var props = Entities.getEntityProperties(entityID, [ "type" ]); - if (props && props.type == "Web") { - print("Entity Web removed " + entityID); - removeEntityData(entityID); - } -} - /******************************************************************************* * Entities (to remark) cache structure for showing entities markers ******************************************************************************/ -var entitiesData = {}; // by entityID -var entitiesByOverlayID = {}; // by overlayID -var entitiesIcons = []; // a parallel list of icons (overlays) to easily run - // through - -var ICON_ENTITY_WEB_MODEL_URL = Script.resolvePath("../assets/images/web.svg"); -var ICON_ENTITY_IMG_MODEL_URL = Script - .resolvePath("../assets/models/teleport-cancel.fbx"); // FIXME - use - // correct - // model&texture var ICON_ENTITY_DEFAULT_DIMENSIONS = { x : 0.10, y : 0.00001, @@ -1169,7 +1097,7 @@ var entityIconModelDimensionsVal = { y : 0.00001, z : 0 }; -function entityIconModelDimensions(y) { +function teleportIconModelDimensions(y) { // given the current height, give a size // TODO: receive entity.position.y and substract to radarHeight var xz = -0.002831 * (radarHeight - y) + 0.1; @@ -1178,122 +1106,6 @@ function entityIconModelDimensions(y) { // reuse object return entityIconModelDimensionsVal; } -/* - * entityIconPlaneDimensions: similar to entityIconModelDimensions but using xy - * plane - */ -function entityIconPlaneDimensions(y) { - var dim = entityIconModelDimensions(y); - var z = dim.z; - dim.z = dim.y; - dim.y = z; - return dim; -} - -function currentOverlayForEntity(QUuid) { - if (entitiesData[QUuid] != undefined) { - return entitiesData[QUuid].icon; - } else { - return null; - } -} - -function saveEntityData(QUuid, planar) { - if (QUuid == null) - return; - var entity = Entities.getEntityProperties(QUuid, [ "position" ]); - printd("entity added save entity " + QUuid); - if (entitiesData[QUuid] != undefined) { - entitiesData[QUuid].position = entity.position; - } else { - var entityIcon = Overlays.addOverlay("image3d", { - subImage : { - x : 0, - y : 0, - width : 150, - height : 150 - }, - url : ICON_ENTITY_WEB_MODEL_URL, - dimensions : ICON_ENTITY_DEFAULT_DIMENSIONS, - visible : false, - ignoreRayIntersection : false, - orientation : Quat.fromPitchYawRollDegrees(-90, 0, 0) - }); - - entitiesIcons.push(entityIcon); - entitiesData[QUuid] = { - position : entity.position, - icon : entityIcon - }; - entitiesByOverlayID[entityIcon] = QUuid; - } -} - -function removeEntityData(QUuid) { - if (QUuid == null) - return; - - var itsOverlay = currentOverlayForEntity(QUuid); - if (itsOverlay != null) { - Overlays.deleteOverlay(itsOverlay); - delete entitiesByOverlayID[itsOverlay]; - } - var idx = entitiesIcons.indexOf(itsOverlay); - entitiesIcons.splice(idx, 1); - - delete entitiesData[QUuid]; -} - -/******************************************************************************* - * Entities to remark Icon/Markers rendering - ******************************************************************************/ - -function hideAllEntitiesIcons() { - var len = entitiesIcons.length; - for (var i = 0; i < len; i++) { - Overlays.editOverlay(entitiesIcons[i], { - visible : false - }); - } -} - -function renderAllEntitiesIcons() { - var entityPos; - var entityProps; - - for ( var QUuid in entitiesData) { - if (entitiesData.hasOwnProperty(QUuid)) { - entityProps = Entities.getEntityProperties(QUuid, [ "position", - "visible" ]); - if (entityProps != null) { - entityPos = entityProps.position; - var planeDimensions = entityIconPlaneDimensions(entityPos.y); // plane overlays uses - // xy instead of xz - if (entitiesData[QUuid].icon != undefined && entityPos) { - var iconPos = findLineToHeightIntersectionCoords( - entityPos.x, - entityPos.y - + RADAR_ICONS_APPARENT_DISTANCE_TO_AVATAR_BASE, - entityPos.z, Camera.position.x, Camera.position.y, - Camera.position.z, Camera.position.y - - RADAR_CAMERA_DISTANCE_TO_ICONS); - if (!iconPos) { - printd("entity icon pos bad for " + QUuid); - continue; - } - var iconDimensions = entityIconModelDimensions(entityPos.y); - var dimensions = entitiesData[QUuid].planar ? planeDimensions - : iconDimensions; - Overlays.editOverlay(entitiesData[QUuid].icon, { - visible : entityProps.visible, - dimensions : dimensions, - position : iconPos - }); - } - } - } - } -} /******************************************************************************* * @@ -1304,11 +1116,7 @@ function startRadar() { saveAllOthersAvatarsData(); Camera.mode = "independent"; - Camera.position = { - x : MyAvatar.position.x, - y : radarHeight, - z : MyAvatar.position.z - }; + initCameraOverMyAvatar(); Camera.orientation = Quat.fromPitchYawRollDegrees(-90, 0, 0); radar = true; @@ -1326,7 +1134,6 @@ function endRadar() { Controller.setVPadEnabled(true); disconnectRadarModeEvents(); - hideAllEntitiesIcons(); hideAllAvatarIcons(); } @@ -1360,12 +1167,10 @@ function updateRadar() { // Update avatar icons if (startedDraggingCamera) { hideAllAvatarIcons(); - hideAllEntitiesIcons(); startedDraggingCamera = false; } else if (!draggingCamera) { renderMyAvatarIcon(); renderAllOthersAvatarIcons(); - renderAllEntitiesIcons(); } } @@ -1373,36 +1178,15 @@ function valueIfDefined(value) { return value !== undefined ? value : ""; } -function entitiesAnalysis() { - var ids = Entities.findEntitiesInFrustum(Camera.frustum); - var entities = []; - for (var i = 0; i < ids.length; i++) { - var id = ids[i]; - var properties = Entities.getEntityProperties(id); - entities.push({ - id : id, - name : properties.name, - type : properties.type, - url : properties.type == "Model" ? properties.modelURL : "", - sourceUrl : properties.sourceUrl, - locked : properties.locked, - visible : properties.visible, - drawCalls : valueIfDefined(properties.renderInfo.drawCalls), - hasScript : properties.script !== "" - }); - } -} - function connectRadarModeEvents() { Script.update.connect(updateRadar); // 60Hz loop Controller.keyPressEvent.connect(keyPressEvent); - Controller.mousePressEvent.connect(mousePress); // single click/touch Controller.touchUpdateEvent.connect(touchUpdate); Window.domainChanged.connect(domainChanged); MyAvatar.positionGoneTo.connect(positionGoneTo); } -function domainChanged() { +function initCameraOverMyAvatar() { radarHeight = MyAvatar.position.y + RADAR_HEIGHT_INIT_DELTA; Camera.position = { x : MyAvatar.position.x, @@ -1411,6 +1195,10 @@ function domainChanged() { }; } +function domainChanged() { + initCameraOverMyAvatar(); +} + function positionGoneTo() { Camera.position = { x : MyAvatar.position.x, @@ -1422,7 +1210,6 @@ function positionGoneTo() { function disconnectRadarModeEvents() { Script.update.disconnect(updateRadar); Controller.keyPressEvent.disconnect(keyPressEvent); - Controller.mousePressEvent.disconnect(mousePress); Controller.touchUpdateEvent.disconnect(touchUpdate); MyAvatar.positionGoneTo.disconnect(positionGoneTo); Window.domainChanged.disconnect(domainChanged); @@ -1436,7 +1223,4 @@ function init() { AvatarList.avatarAddedEvent.connect(avatarAdded); AvatarList.avatarRemovedEvent.connect(avatarRemoved); - - Entities.addingEntity.connect(entityAdded); - Entities.deletingEntity.connect(entityRemoved); } From aceaa510c89a9226170de6c60dc7dd21505e50f7 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 23 Apr 2018 14:47:17 -0700 Subject: [PATCH 007/152] Added referral to physical memory Test. Added menu items - `close` and `about` --- tools/auto-tester/src/Test.cpp | 78 +++++++++++++++++-------- tools/auto-tester/src/Test.h | 2 + tools/auto-tester/src/ui/AutoTester.cpp | 10 ++++ tools/auto-tester/src/ui/AutoTester.h | 2 + tools/auto-tester/src/ui/AutoTester.ui | 24 ++++++++ 5 files changed, 91 insertions(+), 25 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index 99f9025fdd..57806e80f6 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -498,6 +498,12 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { const QString regexAssertGPU(ws + functionAssertGPU + ws + "\\(" + ws + quotedString + ".*"); const QRegularExpression lineAssertGPU = QRegularExpression(regexAssertGPU); + // Assert the correct amount of memory + const QString functionAssertPhysicalMemoryGB(ws + "autoTester" + ws + "\\." + ws + "assertPhysicalMemoryGB"); + const QString regexAssertPhysicalMemoryGB(ws + functionAssertPhysicalMemoryGB + ws + "\\(" + ws + quotedString + ".*"); + const QRegularExpression lineAssertPhysicalMemoryGB = QRegularExpression(regexAssertPhysicalMemoryGB); + + // Each step is either of the following forms: // autoTester.addStepSnapshot("Take snapshot"... // autoTester.addStep("Clean up after test"... @@ -514,18 +520,27 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { if (lineContainingTitle.match(line).hasMatch()) { QStringList tokens = line.split('"'); relevantTextFromTest.title = tokens[1]; + } else if (lineAssertPlatform.match(line).hasMatch()) { QStringList platforms = line.split('"'); relevantTextFromTest.platform = platforms[1]; + } else if (lineAssertDisplay.match(line).hasMatch()) { QStringList displays = line.split('"'); relevantTextFromTest.display = displays[1]; + } else if (lineAssertCPU.match(line).hasMatch()) { QStringList cpus = line.split('"'); relevantTextFromTest.cpu = cpus[1]; + } else if (lineAssertGPU.match(line).hasMatch()) { QStringList gpus = line.split('"'); relevantTextFromTest.gpu = gpus[1]; + + } else if (lineAssertPhysicalMemoryGB.match(line).hasMatch()) { + QStringList physicalMemoryGB = line.split('"'); + relevantTextFromTest.physicalMemoryGB = physicalMemoryGB[1]; + } else if (lineStepSnapshot.match(line).hasMatch()) { QStringList tokens = line.split('"'); QString nameOfStep = tokens[1]; @@ -534,6 +549,7 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { step->text = nameOfStep; step->takeSnapshot = true; relevantTextFromTest.stepList.emplace_back(step); + } else if (lineStep.match(line).hasMatch()) { QStringList tokens = line.split('"'); QString nameOfStep = tokens[1]; @@ -630,62 +646,74 @@ void Test::createMDFile(QString testDirectory) { // Platform QStringList platforms = testScriptLines.platform.split(" ");; - stream << "## Platforms\n"; - stream << "Run the test on each of the following platforms\n"; - for (int i = 0; i < platforms.size(); ++i) { - // Note that the platforms parameter may include extra spaces, these appear as empty strings in the list - if (platforms[i] != QString()) { - stream << " - " << platforms[i] << "\n"; + if (platforms.size() > 0) { + stream << "## Platforms\n"; + stream << "Run the test on each of the following platforms\n"; + for (int i = 0; i < platforms.size(); ++i) { + // Note that the platforms parameter may include extra spaces, these appear as empty strings in the list + if (platforms[i] != QString()) { + stream << " - " << platforms[i] << "\n"; + } } } // Display QStringList displays = testScriptLines.display.split(" "); - stream << "## Displays\n"; - stream << "Run the test on each of the following displays\n"; - for (int i = 0; i < displays.size(); ++i) { - // Note that the displays parameter may include extra spaces, these appear as empty strings in the list - if (displays[i] != QString()) { - stream << " - " << displays[i] << "\n"; + if (displays.size()) { + stream << "## Displays\n"; + stream << "Run the test on each of the following displays\n"; + for (int i = 0; i < displays.size(); ++i) { + // Note that the displays parameter may include extra spaces, these appear as empty strings in the list + if (displays[i] != QString()) { + stream << " - " << displays[i] << "\n"; + } } } // CPU QStringList cpus = testScriptLines.cpu.split(" "); - stream << "## Processors\n"; - stream << "Run the test on each of the following processors\n"; - for (int i = 0; i < cpus.size(); ++i) { - // Note that the cpus parameter may include extra spaces, these appear as empty strings in the list - if (cpus[i] != QString()) { - stream << " - " << cpus[i] << "\n"; + if (cpus.size() > 0) { + stream << "## Processors\n"; + stream << "Run the test on each of the following processors\n"; + for (int i = 0; i < cpus.size(); ++i) { + // Note that the cpus parameter may include extra spaces, these appear as empty strings in the list + if (cpus[i] != QString()) { + stream << " - " << cpus[i] << "\n"; + } } } // GPU QStringList gpus = testScriptLines.gpu.split(" "); - stream << "## Graphics Cards\n"; - stream << "Run the test on graphics cards from each of the following vendors\n"; - for (int i = 0; i < gpus.size(); ++i) { - // Note that the gpus parameter may include extra spaces, these appear as empty strings in the list - if (gpus[i] != QString()) { - stream << " - " << gpus[i] << "\n"; + if (gpus.size() > 0) { + stream << "## Graphics Cards\n"; + stream << "Run the test on graphics cards from each of the following vendors\n"; + for (int i = 0; i < gpus.size(); ++i) { + // Note that the gpus parameter may include extra spaces, these appear as empty strings in the list + if (gpus[i] != QString()) { + stream << " - " << gpus[i] << "\n"; + } } } stream << "## Steps\n"; stream << "Press space bar to advance step by step\n\n"; + // Note that snapshots of step n are taken in step n+1 + // (this implies that if the LAST step requests a snapshot then this will not work - caveat emptor) int snapShotIndex { 0 }; for (size_t i = 0; i < testScriptLines.stepList.size(); ++i) { stream << "### Step " << QString::number(i + 1) << "\n"; stream << "- " << testScriptLines.stepList[i]->text << "\n"; - if (testScriptLines.stepList[i]->takeSnapshot) { + if ((i + 1 < testScriptLines.stepList.size()) && testScriptLines.stepList[i + 1]->takeSnapshot) { stream << "- ![](./ExpectedImage_" << QString::number(snapShotIndex).rightJustified(5, '0') << ".png)\n"; ++snapShotIndex; } } mdFile.close(); + + messageBox.information(0, "Success", "Test MD file " + mdFilename + " has been created"); } void Test::createTestsOutline() { diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index e69459fef2..7f5553f9e3 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -34,6 +34,8 @@ public: QString display; QString cpu; QString gpu; + QString physicalMemoryGB; + StepList stepList; }; diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index 21acfe9569..3f7d2cba28 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -10,6 +10,8 @@ // #include "AutoTester.h" +#include + AutoTester::AutoTester(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); ui.checkBoxInteractiveMode->setChecked(true); @@ -18,6 +20,9 @@ AutoTester::AutoTester(QWidget *parent) : QMainWindow(parent) { test = new Test(); signalMapper = new QSignalMapper(); + + connect(ui.actionClose, &QAction::triggered, this, &AutoTester::on_closeButton_clicked); + connect(ui.actionAbout, &QAction::triggered, this, &AutoTester::about); } void AutoTester::on_evaluateTestsButton_clicked() { @@ -100,3 +105,8 @@ void AutoTester::saveImage(int index) { ui.progressBar->setValue(_numberOfImagesDownloaded); } } + +void AutoTester::about() { + QMessageBox messageBox; + messageBox.information(0, "About", QString("Built ") + __DATE__ + " : " + __TIME__); +} \ No newline at end of file diff --git a/tools/auto-tester/src/ui/AutoTester.h b/tools/auto-tester/src/ui/AutoTester.h index 1788e97177..03cb7fbcec 100644 --- a/tools/auto-tester/src/ui/AutoTester.h +++ b/tools/auto-tester/src/ui/AutoTester.h @@ -37,6 +37,8 @@ private slots: void saveImage(int index); + void about(); + private: Ui::AutoTesterClass ui; Test* test; diff --git a/tools/auto-tester/src/ui/AutoTester.ui b/tools/auto-tester/src/ui/AutoTester.ui index 2eb1314481..c5115d69b2 100644 --- a/tools/auto-tester/src/ui/AutoTester.ui +++ b/tools/auto-tester/src/ui/AutoTester.ui @@ -157,6 +157,20 @@ 21 + + + File + + + + + + Help + + + + + @@ -167,6 +181,16 @@ + + + Close + + + + + About + + From 99ad51189c66ed5e6c2f425c55d39be9953df464 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 24 Apr 2018 23:03:56 +0100 Subject: [PATCH 008/152] fix browse asset filtering added support for list of filters using formatting consistent with other implementations, e.g: (*.png *.wav) --- .../assetDialog/AssetDialogContent.qml | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml index 84f4c694ff..7c8a735ead 100644 --- a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml +++ b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml @@ -19,14 +19,14 @@ import "../fileDialog" Item { // Set from OffscreenUi::assetDialog() property alias dir: assetTableModel.folder - property alias filter: selectionType.filtersString // FIXME: Currently only supports simple filters, "*.xxx". + property alias filter: selectionType.filtersString property int options // Not used. property bool selectDirectory: false // Not implemented. - //property bool saveDialog: false; - //property bool multiSelect: false; + // property bool saveDialog: false; + // property bool multiSelect: false; property bool singleClickNavigate: false @@ -84,7 +84,7 @@ Item { size: 28 width: height enabled: destination !== "" - //onClicked: d.navigateHome(); + // onClicked: d.navigateHome(); onClicked: assetTableModel.folder = destination; } } @@ -227,7 +227,9 @@ Item { function onGetAllMappings(error, map) { var mappings, - fileTypeFilter, + fileTypeFilters = [], + filterListStart, + filterListEnd, index, path, fileName, @@ -248,7 +250,14 @@ Item { if (error === "") { mappings = Object.keys(map); - fileTypeFilter = filter.replace("*", "").toLowerCase(); + filter = filter.replace(/\s/g, ''); + filterListStart = filter.indexOf("("); + filterListEnd = filter.indexOf(")"); + if (filterListStart !== -1 && filterListEnd !== -1) { + fileTypeFilters = filter.substring(filterListStart + 2, filterListEnd).toLowerCase().split("*"); + } else if (filter !== "") { + fileTypeFilters[0] = filter.replace("*", "").toLowerCase(); + } for (i = 0, length = mappings.length; i < length; i++) { index = mappings[i].lastIndexOf("/"); @@ -259,7 +268,24 @@ Item { fileIsDir = false; isValid = false; - if (fileType.toLowerCase() === fileTypeFilter) { + if (fileTypeFilters.length > 1) { + if (fileTypeFilters.indexOf(fileType.toLowerCase()) !== -1) { + if (path === folder) { + isValid = !selectDirectory; + } else if (path.length > folder.length) { + subDirectory = path.slice(folder.length); + index = subDirectory.indexOf("/"); + if (index === subDirectory.lastIndexOf("/")) { + fileName = subDirectory.slice(0, index); + if (subDirectories.indexOf(fileName) === -1) { + fileIsDir = true; + isValid = true; + subDirectories.push(fileName); + } + } + } + } + } else if (fileType.toLowerCase() === fileTypeFilters[0] || fileTypeFilters.length === 0) { if (path === folder) { isValid = !selectDirectory; } else if (path.length > folder.length) { From 21a9525a737e3db268cabdd82c0c60504a54444f Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 24 Apr 2018 17:52:12 -0700 Subject: [PATCH 009/152] Version of HMACAuth with exposed lock Client is responsible for locking between adding and retrieving. Fixes a likely race. --- libraries/networking/src/HMACAuth.cpp | 11 ++++++----- libraries/networking/src/HMACAuth.h | 2 ++ libraries/networking/src/LimitedNodeList.cpp | 5 +++-- libraries/networking/src/NLPacket.cpp | 1 + 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index 42b5c48d93..e276e64b40 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -68,7 +68,7 @@ bool HMACAuth::setKey(const char* keyValue, int keyLen) { return false; } - QMutexLocker lock(&_lock); + //QMutexLocker lock(&_lock); return (bool) HMAC_Init_ex(_hmacContext, keyValue, keyLen, sslStruct, nullptr); } @@ -78,16 +78,17 @@ bool HMACAuth::setKey(const QUuid& uidKey) { } bool HMACAuth::addData(const char* data, int dataLen) { - QMutexLocker lock(&_lock); + //QMutexLocker lock(&_lock); return (bool) HMAC_Update(_hmacContext, reinterpret_cast(data), dataLen); } HMACAuth::HMACHash HMACAuth::result() { HMACHash hashValue(EVP_MAX_MD_SIZE); unsigned int hashLen; - QMutexLocker lock(&_lock); - HMAC_Final(_hmacContext, &hashValue[0], &hashLen); - hashValue.resize((size_t) hashLen); + //QMutexLocker lock(&_lock); + if (HMAC_Final(_hmacContext, &hashValue[0], &hashLen)) { + hashValue.resize((size_t)hashLen); + } // Clear state for possible reuse. HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr); return hashValue; diff --git a/libraries/networking/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h index 0bf7a86ec1..ba1ec78214 100644 --- a/libraries/networking/src/HMACAuth.h +++ b/libraries/networking/src/HMACAuth.h @@ -26,6 +26,8 @@ public: explicit HMACAuth(AuthMethod authMethod = MD5); ~HMACAuth(); + QMutex& getLock() { return _lock; } + bool setKey(const char* keyValue, int keyLen); bool setKey(const QUuid& uidKey); bool addData(const char* data, int dataLen); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 8d177ca534..d66dd644d5 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -333,13 +333,14 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet); QByteArray expectedHash = NLPacket::hashForPacketAndHMAC(packet, sourceNode->getAuthenticateHash()); - // check if the md5 hash in the header matches the hash we would expect + // check if the HMAC-md5 hash in the header matches the hash we would expect if (packetHeaderHash != expectedHash) { static QMultiMap hashDebugSuppressMap; if (!hashDebugSuppressMap.contains(sourceID, headerType)) { - qCDebug(networking) << packetHeaderHash << expectedHash; qCDebug(networking) << "Packet hash mismatch on" << headerType << "- Sender" << sourceID; + qCDebug(networking) << "Packet len:" << packet.getDataSize() << "Expected hash:" << + expectedHash.toHex() << "Actual:" << packetHeaderHash.toHex(); hashDebugSuppressMap.insert(sourceID, headerType); } diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 3355e1cd6b..09a7b78840 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -157,6 +157,7 @@ QByteArray NLPacket::hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& h + NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH; // add the packet payload and the connection UUID + QMutexLocker hashLock(&hash.getLock()); hash.addData(packet.getData() + offset, packet.getDataSize() - offset); auto hashResult { hash.result() }; return QByteArray((const char*) hashResult.data(), (int) hashResult.size()); From bd72350287c31a12edc65094e05febcf2343f132 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 25 Apr 2018 12:47:55 +0100 Subject: [PATCH 010/152] describe magic number --- .../resources/qml/dialogs/assetDialog/AssetDialogContent.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml index 7c8a735ead..cd9ce226c0 100644 --- a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml +++ b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml @@ -254,7 +254,8 @@ Item { filterListStart = filter.indexOf("("); filterListEnd = filter.indexOf(")"); if (filterListStart !== -1 && filterListEnd !== -1) { - fileTypeFilters = filter.substring(filterListStart + 2, filterListEnd).toLowerCase().split("*"); + var FIRST_EXTENSION_OFFSET = 2; + fileTypeFilters = filter.substring(filterListStart + FIRST_EXTENSION_OFFSET, filterListEnd).toLowerCase().split("*"); } else if (filter !== "") { fileTypeFilters[0] = filter.replace("*", "").toLowerCase(); } From bd6b6c94232d7308842df7bddbff68a9b5e7b1b6 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 25 Apr 2018 12:57:46 +0100 Subject: [PATCH 011/152] fix content within 128 columns --- .../resources/qml/dialogs/assetDialog/AssetDialogContent.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml index cd9ce226c0..ed442aa191 100644 --- a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml +++ b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml @@ -255,7 +255,8 @@ Item { filterListEnd = filter.indexOf(")"); if (filterListStart !== -1 && filterListEnd !== -1) { var FIRST_EXTENSION_OFFSET = 2; - fileTypeFilters = filter.substring(filterListStart + FIRST_EXTENSION_OFFSET, filterListEnd).toLowerCase().split("*"); + fileTypeFilters = filter.substring(filterListStart + FIRST_EXTENSION_OFFSET + , filterListEnd).toLowerCase().split("*"); } else if (filter !== "") { fileTypeFilters[0] = filter.replace("*", "").toLowerCase(); } From 3233cc43ac8d12a48e500130c6b7a91fbcff448c Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 25 Apr 2018 10:30:50 -0700 Subject: [PATCH 012/152] Revert "Merge pull request #12981 from birarda/bug/revert-hmac" This reverts commit 91b93db0c5f27a5b5c0282780ee56102078224be, reversing changes made to 6062f21da114f34164ba80db7e31bf45b959626e. --- libraries/networking/src/HMACAuth.cpp | 94 +++++++++++++++++++ libraries/networking/src/HMACAuth.h | 40 ++++++++ libraries/networking/src/LimitedNodeList.cpp | 36 +++---- libraries/networking/src/LimitedNodeList.h | 10 +- libraries/networking/src/NLPacket.cpp | 16 ++-- libraries/networking/src/NLPacket.h | 8 +- libraries/networking/src/Node.cpp | 14 ++- libraries/networking/src/Node.h | 5 +- .../networking/src/udt/PacketHeaders.cpp | 2 +- 9 files changed, 186 insertions(+), 39 deletions(-) create mode 100644 libraries/networking/src/HMACAuth.cpp create mode 100644 libraries/networking/src/HMACAuth.h diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp new file mode 100644 index 0000000000..42b5c48d93 --- /dev/null +++ b/libraries/networking/src/HMACAuth.cpp @@ -0,0 +1,94 @@ +// +// HMACAuth.cpp +// libraries/networking/src +// +// Created by Simon Walton on 3/19/2018. +// 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 +#include + +#include "HMACAuth.h" + +#include + +#if OPENSSL_VERSION_NUMBER >= 0x10100000 +HMACAuth::HMACAuth(AuthMethod authMethod) + : _hmacContext(HMAC_CTX_new()) + , _authMethod(authMethod) { } + +HMACAuth::~HMACAuth() +{ + HMAC_CTX_free(_hmacContext); +} + +#else + +HMACAuth::HMACAuth(AuthMethod authMethod) + : _hmacContext(new HMAC_CTX()) + , _authMethod(authMethod) { + HMAC_CTX_init(_hmacContext); +} + +HMACAuth::~HMACAuth() { + HMAC_CTX_cleanup(_hmacContext); + delete _hmacContext; +} +#endif + +bool HMACAuth::setKey(const char* keyValue, int keyLen) { + const EVP_MD* sslStruct = nullptr; + + switch (_authMethod) { + case MD5: + sslStruct = EVP_md5(); + break; + + case SHA1: + sslStruct = EVP_sha1(); + break; + + case SHA224: + sslStruct = EVP_sha224(); + break; + + case SHA256: + sslStruct = EVP_sha256(); + break; + + case RIPEMD160: + sslStruct = EVP_ripemd160(); + break; + + default: + return false; + } + + QMutexLocker lock(&_lock); + return (bool) HMAC_Init_ex(_hmacContext, keyValue, keyLen, sslStruct, nullptr); +} + +bool HMACAuth::setKey(const QUuid& uidKey) { + const QByteArray rfcBytes(uidKey.toRfc4122()); + return setKey(rfcBytes.constData(), rfcBytes.length()); +} + +bool HMACAuth::addData(const char* data, int dataLen) { + QMutexLocker lock(&_lock); + return (bool) HMAC_Update(_hmacContext, reinterpret_cast(data), dataLen); +} + +HMACAuth::HMACHash HMACAuth::result() { + HMACHash hashValue(EVP_MAX_MD_SIZE); + unsigned int hashLen; + QMutexLocker lock(&_lock); + HMAC_Final(_hmacContext, &hashValue[0], &hashLen); + hashValue.resize((size_t) hashLen); + // Clear state for possible reuse. + HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr); + return hashValue; +} diff --git a/libraries/networking/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h new file mode 100644 index 0000000000..0bf7a86ec1 --- /dev/null +++ b/libraries/networking/src/HMACAuth.h @@ -0,0 +1,40 @@ +// +// HMACAuth.h +// libraries/networking/src +// +// Created by Simon Walton on 3/19/2018. +// 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_HMACAuth_h +#define hifi_HMACAuth_h + +#include +#include +#include + +class QUuid; + +class HMACAuth { +public: + enum AuthMethod { MD5, SHA1, SHA224, SHA256, RIPEMD160 }; + using HMACHash = std::vector; + + explicit HMACAuth(AuthMethod authMethod = MD5); + ~HMACAuth(); + + bool setKey(const char* keyValue, int keyLen); + bool setKey(const QUuid& uidKey); + bool addData(const char* data, int dataLen); + HMACHash result(); + +private: + QMutex _lock; + struct hmac_ctx_st* _hmacContext; + AuthMethod _authMethod; +}; + +#endif // hifi_HMACAuth_h diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 92385e99b0..8d177ca534 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -36,6 +36,7 @@ #include "HifiSockAddr.h" #include "NetworkLogging.h" #include "udt/Packet.h" +#include "HMACAuth.h" static Setting::Handle LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0); @@ -330,7 +331,7 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe if (verifiedPacket && !ignoreVerification) { QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet); - QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, sourceNode->getConnectionSecret()); + QByteArray expectedHash = NLPacket::hashForPacketAndHMAC(packet, sourceNode->getAuthenticateHash()); // check if the md5 hash in the header matches the hash we would expect if (packetHeaderHash != expectedHash) { @@ -370,15 +371,15 @@ void LimitedNodeList::collectPacketStats(const NLPacket& packet) { _numCollectedBytes += packet.getDataSize(); } -void LimitedNodeList::fillPacketHeader(const NLPacket& packet, const QUuid& connectionSecret) { +void LimitedNodeList::fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth) { if (!PacketTypeEnum::getNonSourcedPackets().contains(packet.getType())) { packet.writeSourceID(getSessionLocalID()); } - if (!connectionSecret.isNull() + if (hmacAuth && !PacketTypeEnum::getNonSourcedPackets().contains(packet.getType()) && !PacketTypeEnum::getNonVerifiedPackets().contains(packet.getType())) { - packet.writeVerificationHashGivenSecret(connectionSecret); + packet.writeVerificationHash(*hmacAuth); } } @@ -394,17 +395,17 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node& emit dataSent(destinationNode.getType(), packet.getDataSize()); destinationNode.recordBytesSent(packet.getDataSize()); - return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getConnectionSecret()); + return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), &destinationNode.getAuthenticateHash()); } qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret) { + HMACAuth* hmacAuth) { Q_ASSERT(!packet.isPartOfMessage()); Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket", "Trying to send a reliable packet unreliably."); collectPacketStats(packet); - fillPacketHeader(packet, connectionSecret); + fillPacketHeader(packet, hmacAuth); return _nodeSocket.writePacket(packet, sockAddr); } @@ -417,7 +418,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& emit dataSent(destinationNode.getType(), packet->getDataSize()); destinationNode.recordBytesSent(packet->getDataSize()); - return sendPacket(std::move(packet), *activeSocket, destinationNode.getConnectionSecret()); + return sendPacket(std::move(packet), *activeSocket, &destinationNode.getAuthenticateHash()); } else { qCDebug(networking) << "LimitedNodeList::sendPacket called without active socket for node" << destinationNode << "- not sending"; return ERROR_SENDING_PACKET_BYTES; @@ -425,18 +426,18 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& } qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret) { + HMACAuth* hmacAuth) { Q_ASSERT(!packet->isPartOfMessage()); if (packet->isReliable()) { collectPacketStats(*packet); - fillPacketHeader(*packet, connectionSecret); + fillPacketHeader(*packet, hmacAuth); auto size = packet->getDataSize(); _nodeSocket.writePacket(std::move(packet), sockAddr); return size; } else { - return sendUnreliablePacket(*packet, sockAddr, connectionSecret); + return sendUnreliablePacket(*packet, sockAddr, hmacAuth); } } @@ -445,13 +446,14 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi if (activeSocket) { qint64 bytesSent = 0; - auto connectionSecret = destinationNode.getConnectionSecret(); + auto& connectionHash = destinationNode.getAuthenticateHash(); // close the last packet in the list packetList.closeCurrentPacket(); while (!packetList._packets.empty()) { - bytesSent += sendPacket(packetList.takeFront(), *activeSocket, connectionSecret); + bytesSent += sendPacket(packetList.takeFront(), *activeSocket, + &connectionHash); } emit dataSent(destinationNode.getType(), bytesSent); @@ -464,14 +466,14 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi } qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret) { + HMACAuth* hmacAuth) { qint64 bytesSent = 0; // close the last packet in the list packetList.closeCurrentPacket(); while (!packetList._packets.empty()) { - bytesSent += sendPacket(packetList.takeFront(), sockAddr, connectionSecret); + bytesSent += sendPacket(packetList.takeFront(), sockAddr, hmacAuth); } return bytesSent; @@ -499,7 +501,7 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr packetList, for (std::unique_ptr& packet : packetList->_packets) { NLPacket* nlPacket = static_cast(packet.get()); collectPacketStats(*nlPacket); - fillPacketHeader(*nlPacket, destinationNode.getConnectionSecret()); + fillPacketHeader(*nlPacket, &destinationNode.getAuthenticateHash()); } return _nodeSocket.writePacketList(std::move(packetList), *activeSocket); @@ -522,7 +524,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& auto& destinationSockAddr = (overridenSockAddr.isNull()) ? *destinationNode.getActiveSocket() : overridenSockAddr; - return sendPacket(std::move(packet), destinationSockAddr, destinationNode.getConnectionSecret()); + return sendPacket(std::move(packet), destinationSockAddr, &destinationNode.getAuthenticateHash()); } int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer message, SharedNodePointer sendingNode) { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 3d6fd0cd91..05374bbfbb 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -138,19 +138,17 @@ public: // use sendUnreliablePacket to send an unreliable packet (that you do not need to move) // either to a node (via its active socket) or to a manual sockaddr qint64 sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode); - qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret = QUuid()); + qint64 sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, HMACAuth* hmacAuth = nullptr); // use sendPacket to send a moved unreliable or reliable NL packet to a node's active socket or manual sockaddr qint64 sendPacket(std::unique_ptr packet, const Node& destinationNode); - qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret = QUuid()); + qint64 sendPacket(std::unique_ptr packet, const HifiSockAddr& sockAddr, HMACAuth* hmacAuth = nullptr); // use sendUnreliableUnorderedPacketList to unreliably send separate packets from the packet list // either to a node's active socket or to a manual sockaddr qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const Node& destinationNode); qint64 sendUnreliableUnorderedPacketList(NLPacketList& packetList, const HifiSockAddr& sockAddr, - const QUuid& connectionSecret = QUuid()); + HMACAuth* hmacAuth = nullptr); // use sendPacketList to send reliable packet lists (ordered or unordered) to a node's active socket // or to a manual sock addr @@ -372,7 +370,7 @@ protected: qint64 writePacket(const NLPacket& packet, const HifiSockAddr& destinationSockAddr, const QUuid& connectionSecret = QUuid()); void collectPacketStats(const NLPacket& packet); - void fillPacketHeader(const NLPacket& packet, const QUuid& connectionSecret = QUuid()); + void fillPacketHeader(const NLPacket& packet, HMACAuth* hmacAuth = nullptr); void setLocalSocket(const HifiSockAddr& sockAddr); diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index ac3fbc966b..3355e1cd6b 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -11,6 +11,8 @@ #include "NLPacket.h" +#include "HMACAuth.h" + int NLPacket::localHeaderSize(PacketType type) { bool nonSourced = PacketTypeEnum::getNonSourcedPackets().contains(type); bool nonVerified = PacketTypeEnum::getNonVerifiedPackets().contains(type); @@ -150,18 +152,14 @@ QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH); } -QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret) { - QCryptographicHash hash(QCryptographicHash::Md5); - +QByteArray NLPacket::hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash) { int offset = Packet::totalHeaderSize(packet.isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH; // add the packet payload and the connection UUID hash.addData(packet.getData() + offset, packet.getDataSize() - offset); - hash.addData(connectionSecret.toRfc4122()); - - // return the hash - return hash.result(); + auto hashResult { hash.result() }; + return QByteArray((const char*) hashResult.data(), (int) hashResult.size()); } void NLPacket::writeTypeAndVersion() { @@ -214,14 +212,14 @@ void NLPacket::writeSourceID(LocalID sourceID) const { _sourceID = sourceID; } -void NLPacket::writeVerificationHashGivenSecret(const QUuid& connectionSecret) const { +void NLPacket::writeVerificationHash(HMACAuth& hmacAuth) const { Q_ASSERT(!PacketTypeEnum::getNonSourcedPackets().contains(_type) && !PacketTypeEnum::getNonVerifiedPackets().contains(_type)); auto offset = Packet::totalHeaderSize(isPartOfMessage()) + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_LOCALID; - QByteArray verificationHash = hashForPacketAndSecret(*this, connectionSecret); + QByteArray verificationHash = hashForPacketAndHMAC(*this, hmacAuth); memcpy(_packet.get() + offset, verificationHash.data(), verificationHash.size()); } diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index 9b07bc6581..4103f2068e 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -18,6 +18,8 @@ #include "udt/Packet.h" +class HMACAuth; + class NLPacket : public udt::Packet { Q_OBJECT public: @@ -69,7 +71,7 @@ public: static LocalID sourceIDInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet); - static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret); + static QByteArray hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& hash); PacketType getType() const { return _type; } void setType(PacketType type); @@ -78,9 +80,9 @@ public: void setVersion(PacketVersion version); LocalID getSourceID() const { return _sourceID; } - + void writeSourceID(LocalID sourceID) const; - void writeVerificationHashGivenSecret(const QUuid& connectionSecret) const; + void writeVerificationHash(HMACAuth& hmacAuth) const; protected: diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index 73b7c44e7e..7979b36e30 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -86,10 +86,10 @@ NodeType_t NodeType::fromString(QString type) { Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, - const HifiSockAddr& localSocket, QObject* parent) : + const HifiSockAddr& localSocket, QObject* parent) : NetworkPeer(uuid, publicSocket, localSocket, parent), _type(type), - _pingMs(-1), // "Uninitialized" + _authenticateHash(new HMACAuth), _pingMs(-1), // "Uninitialized" _clockSkewUsec(0), _mutex(), _clockSkewMovingPercentile(30, 0.8f) // moving 80th percentile of 30 samples @@ -108,6 +108,7 @@ void Node::setType(char type) { _symmetricSocket.setObjectName(typeString); } + void Node::updateClockSkewUsec(qint64 clockSkewSample) { _clockSkewMovingPercentile.updatePercentile(clockSkewSample); _clockSkewUsec = (quint64)_clockSkewMovingPercentile.getValueAtPercentile(); @@ -194,3 +195,12 @@ QDebug operator<<(QDebug debug, const Node& node) { debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket(); return debug.nospace(); } + +void Node::setConnectionSecret(const QUuid& connectionSecret) { + if (_connectionSecret == connectionSecret) { + return; + } + + _connectionSecret = connectionSecret; + _authenticateHash->setKey(_connectionSecret); +} diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index 93b6a649d4..5b3b559582 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -33,6 +33,7 @@ #include "SimpleMovingAverage.h" #include "MovingPercentile.h" #include "NodePermissions.h" +#include "HMACAuth.h" class Node : public NetworkPeer { Q_OBJECT @@ -55,7 +56,8 @@ public: void setIsUpstream(bool isUpstream) { _isUpstream = isUpstream; } const QUuid& getConnectionSecret() const { return _connectionSecret; } - void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; } + void setConnectionSecret(const QUuid& connectionSecret); + HMACAuth& getAuthenticateHash() const { return *_authenticateHash; } NodeData* getLinkedData() const { return _linkedData.get(); } void setLinkedData(std::unique_ptr linkedData) { _linkedData = std::move(linkedData); } @@ -97,6 +99,7 @@ private: NodeType_t _type; QUuid _connectionSecret; + std::unique_ptr _authenticateHash; std::unique_ptr _linkedData; bool _isReplicated { false }; int _pingMs; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 98b0e1d892..db466a0403 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -91,7 +91,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::Ping: return static_cast(PingVersion::IncludeConnectionID); default: - return 20; + return 19; } } From 4fa11f116fb17847c5bdcee167301f16d94cc2ce Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 25 Apr 2018 14:41:16 -0700 Subject: [PATCH 013/152] Add & use HMACAuth method that calculates hash atomically To avoid issues with race conditions involving separate addData() and result() calls use a method that does both in the lock. --- libraries/networking/src/HMACAuth.cpp | 25 +++++++++++++++++++++---- libraries/networking/src/HMACAuth.h | 5 +++-- libraries/networking/src/NLPacket.cpp | 7 ++++--- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index e276e64b40..8aa2fea6a9 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -68,7 +68,7 @@ bool HMACAuth::setKey(const char* keyValue, int keyLen) { return false; } - //QMutexLocker lock(&_lock); + QMutexLocker lock(&_lock); return (bool) HMAC_Init_ex(_hmacContext, keyValue, keyLen, sslStruct, nullptr); } @@ -78,14 +78,14 @@ bool HMACAuth::setKey(const QUuid& uidKey) { } bool HMACAuth::addData(const char* data, int dataLen) { - //QMutexLocker lock(&_lock); + QMutexLocker lock(&_lock); return (bool) HMAC_Update(_hmacContext, reinterpret_cast(data), dataLen); } HMACAuth::HMACHash HMACAuth::result() { HMACHash hashValue(EVP_MAX_MD_SIZE); - unsigned int hashLen; - //QMutexLocker lock(&_lock); + unsigned int hashLen; + QMutexLocker lock(&_lock); if (HMAC_Final(_hmacContext, &hashValue[0], &hashLen)) { hashValue.resize((size_t)hashLen); } @@ -93,3 +93,20 @@ HMACAuth::HMACHash HMACAuth::result() { HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr); return hashValue; } + +bool HMACAuth::calculateHash(HMACHash& hashResult, const char* data, int dataLen) { + QMutexLocker lock(&_lock); + if (!HMAC_Update(_hmacContext, reinterpret_cast(data), dataLen)) { + return false; + } + + hashResult.resize(EVP_MAX_MD_SIZE); + unsigned int hashLen; + if (HMAC_Final(_hmacContext, &hashResult[0], &hashLen)) { + hashResult.resize((size_t)hashLen); + // Clear state for possible reuse. + HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr); + return true; + } + return false; +} diff --git a/libraries/networking/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h index ba1ec78214..ec06bfbda2 100644 --- a/libraries/networking/src/HMACAuth.h +++ b/libraries/networking/src/HMACAuth.h @@ -26,10 +26,11 @@ public: explicit HMACAuth(AuthMethod authMethod = MD5); ~HMACAuth(); - QMutex& getLock() { return _lock; } - bool setKey(const char* keyValue, int keyLen); bool setKey(const QUuid& uidKey); + // Calculate complete hash in one. + bool calculateHash(HMACHash& hashResult, const char* data, int dataLen); + // Append data to be hashed. bool addData(const char* data, int dataLen); HMACHash result(); diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 09a7b78840..f946e97bf4 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -157,9 +157,10 @@ QByteArray NLPacket::hashForPacketAndHMAC(const udt::Packet& packet, HMACAuth& h + NUM_BYTES_LOCALID + NUM_BYTES_MD5_HASH; // add the packet payload and the connection UUID - QMutexLocker hashLock(&hash.getLock()); - hash.addData(packet.getData() + offset, packet.getDataSize() - offset); - auto hashResult { hash.result() }; + HMACAuth::HMACHash hashResult; + if (!hash.calculateHash(hashResult, packet.getData() + offset, packet.getDataSize() - offset)) { + return QByteArray(); + } return QByteArray((const char*) hashResult.data(), (int) hashResult.size()); } From 66bd424ae4002a75cd3003f4e97df1322dd2143f Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 25 Apr 2018 14:51:11 -0700 Subject: [PATCH 014/152] Bump default packet version for new HMAC --- libraries/networking/src/udt/PacketHeaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index db466a0403..98b0e1d892 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -91,7 +91,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::Ping: return static_cast(PingVersion::IncludeConnectionID); default: - return 19; + return 20; } } From 9ef56c44a3da38161741cf4dc62f49e786c8e5b1 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 25 Apr 2018 17:08:08 -0700 Subject: [PATCH 015/152] Merge PR12964 to not use verification if not keyed https://github.com/highfidelity/hifi/pull/12964 --- libraries/networking/src/HMACAuth.cpp | 20 +++++++++++++++++--- libraries/networking/src/LimitedNodeList.cpp | 20 ++++++++++++-------- libraries/networking/src/Node.cpp | 6 +++++- libraries/networking/src/Node.h | 4 ++-- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index 8aa2fea6a9..8e57978b5a 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -9,12 +9,14 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "HMACAuth.h" + #include #include -#include "HMACAuth.h" - #include +#include "NetworkLogging.h" +#include #if OPENSSL_VERSION_NUMBER >= 0x10100000 HMACAuth::HMACAuth(AuthMethod authMethod) @@ -86,9 +88,17 @@ HMACAuth::HMACHash HMACAuth::result() { HMACHash hashValue(EVP_MAX_MD_SIZE); unsigned int hashLen; QMutexLocker lock(&_lock); - if (HMAC_Final(_hmacContext, &hashValue[0], &hashLen)) { + + auto hmacResult = HMAC_Final(_hmacContext, &hashValue[0], &hashLen); + + if (hmacResult) { hashValue.resize((size_t)hashLen); + } else { + // the HMAC_FINAL call failed - should not be possible to get into this state + qCWarning(networking) << "Error occured calling HMAC_Final"; + assert(hmacResult); } + // Clear state for possible reuse. HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr); return hashValue; @@ -97,6 +107,8 @@ HMACAuth::HMACHash HMACAuth::result() { bool HMACAuth::calculateHash(HMACHash& hashResult, const char* data, int dataLen) { QMutexLocker lock(&_lock); if (!HMAC_Update(_hmacContext, reinterpret_cast(data), dataLen)) { + qCWarning(networking) << "Error occured calling HMAC_Update"; + assert(false); return false; } @@ -108,5 +120,7 @@ bool HMACAuth::calculateHash(HMACHash& hashResult, const char* data, int dataLen HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr); return true; } + qCWarning(networking) << "Error occured calling HMAC_Final"; + assert(false); return false; } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index d66dd644d5..5457e206f5 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -331,10 +331,14 @@ bool LimitedNodeList::packetSourceAndHashMatchAndTrackBandwidth(const udt::Packe if (verifiedPacket && !ignoreVerification) { QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet); - QByteArray expectedHash = NLPacket::hashForPacketAndHMAC(packet, sourceNode->getAuthenticateHash()); + QByteArray expectedHash; + auto sourceNodeHMACAuth = sourceNode->getAuthenticateHash(); + if (sourceNode->getAuthenticateHash()) { + expectedHash = NLPacket::hashForPacketAndHMAC(packet, *sourceNodeHMACAuth); + } // check if the HMAC-md5 hash in the header matches the hash we would expect - if (packetHeaderHash != expectedHash) { + if (!sourceNodeHMACAuth || packetHeaderHash != expectedHash) { static QMultiMap hashDebugSuppressMap; if (!hashDebugSuppressMap.contains(sourceID, headerType)) { @@ -396,7 +400,7 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node& emit dataSent(destinationNode.getType(), packet.getDataSize()); destinationNode.recordBytesSent(packet.getDataSize()); - return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), &destinationNode.getAuthenticateHash()); + return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getAuthenticateHash()); } qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiSockAddr& sockAddr, @@ -419,7 +423,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& emit dataSent(destinationNode.getType(), packet->getDataSize()); destinationNode.recordBytesSent(packet->getDataSize()); - return sendPacket(std::move(packet), *activeSocket, &destinationNode.getAuthenticateHash()); + return sendPacket(std::move(packet), *activeSocket, destinationNode.getAuthenticateHash()); } else { qCDebug(networking) << "LimitedNodeList::sendPacket called without active socket for node" << destinationNode << "- not sending"; return ERROR_SENDING_PACKET_BYTES; @@ -447,14 +451,14 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi if (activeSocket) { qint64 bytesSent = 0; - auto& connectionHash = destinationNode.getAuthenticateHash(); + auto connectionHash = destinationNode.getAuthenticateHash(); // close the last packet in the list packetList.closeCurrentPacket(); while (!packetList._packets.empty()) { bytesSent += sendPacket(packetList.takeFront(), *activeSocket, - &connectionHash); + connectionHash); } emit dataSent(destinationNode.getType(), bytesSent); @@ -502,7 +506,7 @@ qint64 LimitedNodeList::sendPacketList(std::unique_ptr packetList, for (std::unique_ptr& packet : packetList->_packets) { NLPacket* nlPacket = static_cast(packet.get()); collectPacketStats(*nlPacket); - fillPacketHeader(*nlPacket, &destinationNode.getAuthenticateHash()); + fillPacketHeader(*nlPacket, destinationNode.getAuthenticateHash()); } return _nodeSocket.writePacketList(std::move(packetList), *activeSocket); @@ -525,7 +529,7 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& auto& destinationSockAddr = (overridenSockAddr.isNull()) ? *destinationNode.getActiveSocket() : overridenSockAddr; - return sendPacket(std::move(packet), destinationSockAddr, &destinationNode.getAuthenticateHash()); + return sendPacket(std::move(packet), destinationSockAddr, destinationNode.getAuthenticateHash()); } int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer message, SharedNodePointer sendingNode) { diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index 7979b36e30..8fd8131b10 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -89,7 +89,7 @@ Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket, QObject* parent) : NetworkPeer(uuid, publicSocket, localSocket, parent), _type(type), - _authenticateHash(new HMACAuth), _pingMs(-1), // "Uninitialized" + _pingMs(-1), // "Uninitialized" _clockSkewUsec(0), _mutex(), _clockSkewMovingPercentile(30, 0.8f) // moving 80th percentile of 30 samples @@ -201,6 +201,10 @@ void Node::setConnectionSecret(const QUuid& connectionSecret) { return; } + if (!_authenticateHash) { + _authenticateHash.reset(new HMACAuth()); + } + _connectionSecret = connectionSecret; _authenticateHash->setKey(_connectionSecret); } diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index 5b3b559582..bcfe525aa8 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -57,7 +57,7 @@ public: const QUuid& getConnectionSecret() const { return _connectionSecret; } void setConnectionSecret(const QUuid& connectionSecret); - HMACAuth& getAuthenticateHash() const { return *_authenticateHash; } + HMACAuth* getAuthenticateHash() const { return _authenticateHash.get(); } NodeData* getLinkedData() const { return _linkedData.get(); } void setLinkedData(std::unique_ptr linkedData) { _linkedData = std::move(linkedData); } @@ -99,7 +99,7 @@ private: NodeType_t _type; QUuid _connectionSecret; - std::unique_ptr _authenticateHash; + std::unique_ptr _authenticateHash { nullptr }; std::unique_ptr _linkedData; bool _isReplicated { false }; int _pingMs; From bfbded7beca85e58c1b87801f715d3cee678f027 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 27 Apr 2018 16:57:24 -0700 Subject: [PATCH 016/152] Reset pending domain checkins in more locations --- libraries/networking/src/DomainHandler.cpp | 3 +++ libraries/networking/src/DomainHandler.h | 2 +- libraries/networking/src/NodeList.cpp | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index cd8064c4c0..84af21004d 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -239,6 +239,7 @@ void DomainHandler::activateICELocalSocket() { _domainURL.setHost(_sockAddr.getAddress().toString()); emit domainURLChanged(_domainURL); emit completedSocketDiscovery(); + clearPendingCheckins(); // Clear outstanding count. } void DomainHandler::activateICEPublicSocket() { @@ -248,6 +249,7 @@ void DomainHandler::activateICEPublicSocket() { _domainURL.setHost(_sockAddr.getAddress().toString()); emit domainURLChanged(_domainURL); emit completedSocketDiscovery(); + clearPendingCheckins(); // Clear outstanding count. } QString DomainHandler::getViewPointFromNamedPath(QString namedPath) { @@ -339,6 +341,7 @@ void DomainHandler::processSettingsPacketList(QSharedPointer pa qCDebug(networking) << "Received domain settings: \n" << _settingsObject; } + clearPendingCheckins(); // Reset outstanding check-ins. emit settingsReceived(_settingsObject); } diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 2d4712209d..08908dbaf6 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -97,7 +97,7 @@ public: int getCheckInPacketsSinceLastReply() const { return _checkInPacketsSinceLastReply; } void sentCheckInPacket(); - void domainListReceived() { _checkInPacketsSinceLastReply = 0; } + void clearPendingCheckins() { _checkInPacketsSinceLastReply = 0; } /**jsdoc *

The reasons that you may be refused connection to a domain are defined by numeric values:

diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 04e32f50cb..9d3e5f0e91 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -534,6 +534,8 @@ void NodeList::processDomainServerPathResponse(QSharedPointer m qCDebug(networking) << "Could not go to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery; } + + _domainHandler.clearPendingCheckins(); } void NodeList::handleICEConnectionToDomainServer() { @@ -594,6 +596,8 @@ void NodeList::processDomainServerConnectionTokenPacket(QSharedPointerreadWithoutCopy(NUM_BYTES_RFC4122_UUID))); + + _domainHandler.clearPendingCheckins(); sendDomainServerCheckIn(); } @@ -605,7 +609,7 @@ void NodeList::processDomainServerList(QSharedPointer message) } // this is a packet from the domain server, reset the count of un-replied check-ins - _domainHandler.domainListReceived(); + _domainHandler.clearPendingCheckins(); // emit our signal so listeners know we just heard from the DS emit receivedDomainServerList(); From cf9b089a3c523c26fbe0a60ee142702ee5969971 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Fri, 27 Apr 2018 17:18:16 -0700 Subject: [PATCH 017/152] Added option to set snapshot location (for this execution only) from the command line. --- interface/src/Application.cpp | 15 ++++++++++++--- interface/src/Application.h | 2 ++ interface/src/ui/Snapshot.cpp | 12 +++++++++--- interface/src/ui/Snapshot.h | 4 ++-- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c38caca090..c0fe84894d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -986,13 +986,22 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning())); setProperty(hifi::properties::CRASHED, _previousSessionCrashed); { - const QString TEST_SCRIPT = "--testScript"; + const QString TEST_SCRIPT { "--testScript" }; + const QString TEST_SNAPSHOT_LOCATION { "--testSnapshotLocation" }; + const QStringList args = arguments(); for (int i = 0; i < args.size() - 1; ++i) { if (args.at(i) == TEST_SCRIPT) { QString testScriptPath = args.at(i + 1); if (QFileInfo(testScriptPath).exists()) { setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); + } + } else if (args.at(i) == TEST_SNAPSHOT_LOCATION) { + // Set test snapshot location only if it is a writeable directory + QString pathname(args.at(i + 1)); + QFileInfo fileInfo(pathname); + if (fileInfo.isDir() && fileInfo.isWritable()) { + testSnapshotLocation = pathname; } } } @@ -7259,7 +7268,7 @@ void Application::loadAvatarBrowser() const { void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) { postLambdaEvent([notify, includeAnimated, aspectRatio, filename, this] { // Get a screenshot and save it - QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename); + QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, QString()); // If we're not doing an animated snapshot as well... if (!includeAnimated) { // Tell the dependency manager that the capture of the still snapshot has taken place. @@ -7273,7 +7282,7 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa void Application::takeSecondaryCameraSnapshot(const QString& filename) { postLambdaEvent([filename, this] { - QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename); + QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename, testSnapshotLocation); emit DependencyManager::get()->stillSnapshotTaken(snapshotPath, true); }); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 74b0e5a110..341560bc5b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -719,5 +719,7 @@ private: std::atomic _pendingIdleEvent { true }; std::atomic _pendingRenderEvent { true }; + + QString testSnapshotLocation { QString() }; }; #endif // hifi_Application_h diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 69103a40b5..9eb64dcb14 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -89,10 +89,10 @@ QString Snapshot::saveSnapshot(QImage image, const QString& filename) { QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { // return whatever we get back from saved file for snapshot - return static_cast(savedFileForSnapshot(image, true)); + return static_cast(savedFileForSnapshot(image, true, QString(), QString())); } -QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename) { +QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename, QString userSelectedPathname) { // adding URL to snapshot QUrl currentURL = DependencyManager::get()->currentPublicAddress(); @@ -117,7 +117,13 @@ QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QSt const int IMAGE_QUALITY = 100; if (!isTemporary) { - QString snapshotFullPath = snapshotsLocation.get(); + // If user has requested specific path then use it, else use the application value + QString snapshotFullPath; + if (!userSelectedPathname.isNull()) { + snapshotFullPath = userSelectedPathname; + } else { + snapshotFullPath = snapshotsLocation.get(); + } if (snapshotFullPath.isEmpty()) { snapshotFullPath = OffscreenUi::getExistingDirectory(nullptr, "Choose Snapshots Directory", QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index 62d3ed3db8..20e9e8339f 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -37,7 +37,7 @@ class Snapshot : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY public: - static QString saveSnapshot(QImage image, const QString& filename); + static QString saveSnapshot(QImage image, const QString& filename, const QString& pathname); static QTemporaryFile* saveTempSnapshot(QImage image); static SnapshotMetaData* parseSnapshotData(QString snapshotPath); @@ -51,7 +51,7 @@ public slots: Q_INVOKABLE QString getSnapshotsLocation(); Q_INVOKABLE void setSnapshotsLocation(const QString& location); private: - static QFile* savedFileForSnapshot(QImage & image, bool isTemporary, const QString& userSelectedFilename = QString()); + static QFile* savedFileForSnapshot(QImage & image, bool isTemporary, const QString& userSelectedFilename, QString userSelectedPathname); }; #endif // hifi_Snapshot_h From b994776ebd98314025ecdc86fdffc91ebb42eba1 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Mon, 30 Apr 2018 12:01:37 -0700 Subject: [PATCH 018/152] do not open help on first run --- interface/src/Application.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cd4562da54..6c11286d03 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3166,9 +3166,6 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // If this is a first run we short-circuit the address passed in if (firstRun.get()) { -#if !defined(Q_OS_ANDROID) - showHelp(); -#endif DependencyManager::get()->goToEntry(); sentTo = SENT_TO_ENTRY; firstRun.set(false); From cfc5892d63f342949bf886dc45e99e07809aa0db Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 30 Apr 2018 13:41:56 -0700 Subject: [PATCH 019/152] Only clear check-in count on Domain Query related responses --- libraries/networking/src/DomainHandler.cpp | 3 --- libraries/networking/src/NodeList.cpp | 2 -- 2 files changed, 5 deletions(-) diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 84af21004d..cd8064c4c0 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -239,7 +239,6 @@ void DomainHandler::activateICELocalSocket() { _domainURL.setHost(_sockAddr.getAddress().toString()); emit domainURLChanged(_domainURL); emit completedSocketDiscovery(); - clearPendingCheckins(); // Clear outstanding count. } void DomainHandler::activateICEPublicSocket() { @@ -249,7 +248,6 @@ void DomainHandler::activateICEPublicSocket() { _domainURL.setHost(_sockAddr.getAddress().toString()); emit domainURLChanged(_domainURL); emit completedSocketDiscovery(); - clearPendingCheckins(); // Clear outstanding count. } QString DomainHandler::getViewPointFromNamedPath(QString namedPath) { @@ -341,7 +339,6 @@ void DomainHandler::processSettingsPacketList(QSharedPointer pa qCDebug(networking) << "Received domain settings: \n" << _settingsObject; } - clearPendingCheckins(); // Reset outstanding check-ins. emit settingsReceived(_settingsObject); } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 9d3e5f0e91..4920ea97c7 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -534,8 +534,6 @@ void NodeList::processDomainServerPathResponse(QSharedPointer m qCDebug(networking) << "Could not go to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery; } - - _domainHandler.clearPendingCheckins(); } void NodeList::handleICEConnectionToDomainServer() { From c01fd02de2c5f427e56d75b29b57fcd4122e6d0c Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 30 Apr 2018 17:23:49 -0700 Subject: [PATCH 020/152] Corrected parameter type. --- interface/src/ui/Snapshot.cpp | 2 +- interface/src/ui/Snapshot.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 9eb64dcb14..1af7086933 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -92,7 +92,7 @@ QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { return static_cast(savedFileForSnapshot(image, true, QString(), QString())); } -QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename, QString userSelectedPathname) { +QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename, const QString& userSelectedPathname) { // adding URL to snapshot QUrl currentURL = DependencyManager::get()->currentPublicAddress(); diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index 20e9e8339f..86c860cfcb 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -51,7 +51,7 @@ public slots: Q_INVOKABLE QString getSnapshotsLocation(); Q_INVOKABLE void setSnapshotsLocation(const QString& location); private: - static QFile* savedFileForSnapshot(QImage & image, bool isTemporary, const QString& userSelectedFilename, QString userSelectedPathname); + static QFile* savedFileForSnapshot(QImage & image, bool isTemporary, const QString& userSelectedFilename, const QString& userSelectedPathname); }; #endif // hifi_Snapshot_h From d5610a2f37885a0748129bc3de9dd77261ad12b0 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 30 Apr 2018 17:52:44 -0700 Subject: [PATCH 021/152] WTF... --- interface/src/ui/Snapshot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 1af7086933..d52f01223c 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -73,9 +73,9 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { return data; } -QString Snapshot::saveSnapshot(QImage image, const QString& filename) { +QString Snapshot::saveSnapshot(QImage image, const QString& filename, const QString& pathname) { - QFile* snapshotFile = savedFileForSnapshot(image, false, filename); + QFile* snapshotFile = savedFileForSnapshot(image, false, filename, pathname); // we don't need the snapshot file, so close it, grab its filename and delete it snapshotFile->close(); From b722c80b3f9f367fdc5758064c4110ecc8216221 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 1 May 2018 14:25:33 -0700 Subject: [PATCH 022/152] WIP --- tools/auto-tester/src/ui/AutoTester.cpp | 12 ++++++++---- tools/auto-tester/src/ui/AutoTester.h | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index 3f7d2cba28..860868565a 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -10,8 +10,6 @@ // #include "AutoTester.h" -#include - AutoTester::AutoTester(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); ui.checkBoxInteractiveMode->setChecked(true); @@ -91,11 +89,17 @@ void AutoTester::saveImage(int index) { QPixmap pixmap; pixmap.loadFromData(downloaders[index]->downloadedData()); + int sdf = pixmap.width(); QImage image = pixmap.toImage(); image = image.convertToFormat(QImage::Format_ARGB32); QString fullPathname = _directoryName + "/" + _filenames[index]; - image.save(fullPathname, 0, 100); + if (!image.save(fullPathname, 0, 100)) { + QMessageBox messageBox; + messageBox.information(0, "Test Aborted", "Failed to save image: " + _filenames[index]); + ui.progressBar->setVisible(false); + return; + } ++_numberOfImagesDownloaded; @@ -109,4 +113,4 @@ void AutoTester::saveImage(int index) { void AutoTester::about() { QMessageBox messageBox; messageBox.information(0, "About", QString("Built ") + __DATE__ + " : " + __TIME__); -} \ No newline at end of file +} diff --git a/tools/auto-tester/src/ui/AutoTester.h b/tools/auto-tester/src/ui/AutoTester.h index 03cb7fbcec..d911b6aaff 100644 --- a/tools/auto-tester/src/ui/AutoTester.h +++ b/tools/auto-tester/src/ui/AutoTester.h @@ -52,9 +52,9 @@ private: // Used to enable passing a parameter to slots QSignalMapper* signalMapper; - int _numberOfImagesToDownload; - int _numberOfImagesDownloaded; - int _index; + int _numberOfImagesToDownload { 0 }; + int _numberOfImagesDownloaded { 0 }; + int _index { 0 }; }; #endif // hifi_AutoTester_h \ No newline at end of file From d1bb37874d0ca832fea0d3d78472ce14b3115ef8 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 30 Apr 2018 17:13:44 -0700 Subject: [PATCH 023/152] Prevent crash in ImageProvider when tablet isn't yet initialized --- interface/src/commerce/Wallet.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 3e0e4adf18..42c8b9973d 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -615,9 +615,12 @@ void Wallet::updateImageProvider() { securityImageProvider->setSecurityImage(_securityImage); // inform tablet security image provider - QQmlEngine* tabletEngine = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")->getTabletSurface()->getSurfaceContext()->engine(); - securityImageProvider = reinterpret_cast(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME)); - securityImageProvider->setSecurityImage(_securityImage); + auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); + if (tablet) { + QQmlEngine* tabletEngine = tablet->getTabletSurface()->getSurfaceContext()->engine(); + securityImageProvider = reinterpret_cast(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME)); + securityImageProvider->setSecurityImage(_securityImage); + } } void Wallet::chooseSecurityImage(const QString& filename) { From d5f809c3c08730a3016c772a4b710fd8e7b10d85 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 1 May 2018 09:54:23 -0700 Subject: [PATCH 024/152] Actually fix --- interface/src/commerce/Wallet.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 42c8b9973d..35e6ca1c92 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -615,11 +615,14 @@ void Wallet::updateImageProvider() { securityImageProvider->setSecurityImage(_securityImage); // inform tablet security image provider - auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); + TabletProxy* tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); if (tablet) { - QQmlEngine* tabletEngine = tablet->getTabletSurface()->getSurfaceContext()->engine(); - securityImageProvider = reinterpret_cast(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME)); - securityImageProvider->setSecurityImage(_securityImage); + OffscreenQmlSurface* tabletSurface = tablet->getTabletSurface(); + if (tabletSurface) { + QQmlEngine* tabletEngine = tabletSurface->getSurfaceContext()->engine(); + securityImageProvider = reinterpret_cast(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME)); + securityImageProvider->setSecurityImage(_securityImage); + } } } From a3e4fa84292ab1607ed6cca3a10003ed75825595 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 1 May 2018 15:27:29 -0700 Subject: [PATCH 025/152] Corrected download of images. --- tools/auto-tester/src/Downloader.cpp | 9 +++++++++ tools/auto-tester/src/Test.cpp | 7 +++++-- tools/auto-tester/src/ui/AutoTester.cpp | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/auto-tester/src/Downloader.cpp b/tools/auto-tester/src/Downloader.cpp index 030aa95a19..e66b498bd5 100644 --- a/tools/auto-tester/src/Downloader.cpp +++ b/tools/auto-tester/src/Downloader.cpp @@ -9,6 +9,8 @@ // #include "Downloader.h" +#include + Downloader::Downloader(QUrl imageUrl, QObject *parent) : QObject(parent) { connect( &_networkAccessManager, SIGNAL (finished(QNetworkReply*)), @@ -20,6 +22,13 @@ Downloader::Downloader(QUrl imageUrl, QObject *parent) : QObject(parent) { } void Downloader::fileDownloaded(QNetworkReply* reply) { + QNetworkReply::NetworkError error = reply->error(); + if (error != QNetworkReply::NetworkError::NoError) { + QMessageBox messageBox; + messageBox.information(0, "Test Aborted", "Failed to download image: " + reply->errorString()); + return; + } + _downloadedData = reply->readAll(); //emit a signal diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index 57806e80f6..d0a1606cd8 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -221,8 +221,11 @@ void Test::startTestsEvaluation() { QString expectedImageFilenameTail = currentFilename.left(currentFilename.length() - 4).right(NUM_DIGITS); QString expectedImageStoredFilename = EXPECTED_IMAGE_PREFIX + expectedImageFilenameTail + ".png"; - QString imageURLString("https://github.com/" + githubUser + "/hifi_tests/blob/" + gitHubBranch + "/" + - expectedImagePartialSourceDirectory + "/" + expectedImageStoredFilename + "?raw=true"); + //https://raw.githubusercontent.com/highfidelity/hifi_tests/master/tests/content/entity/zone/zoneOrientation/ExpectedImage_00001.png + + + QString imageURLString("https://raw.githubusercontent.com/" + githubUser + "/hifi_tests/" + gitHubBranch + "/" + + expectedImagePartialSourceDirectory + "/" + expectedImageStoredFilename); expectedImagesURLs << imageURLString; diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index 860868565a..17b1513467 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -86,6 +86,7 @@ void AutoTester::downloadImages(const QStringList& URLs, const QString& director } void AutoTester::saveImage(int index) { + QByteArray q = downloaders[index]->downloadedData(); QPixmap pixmap; pixmap.loadFromData(downloaders[index]->downloadedData()); From 521ae36cbf9fb2f8dc197e150e2b28c1a78e1f40 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 1 May 2018 15:29:22 -0700 Subject: [PATCH 026/152] Make resource swapchains immutable, fix for 14638 --- .../src/gpu/gl/GLBackendOutput.cpp | 4 ++-- .../src/gpu/gl/GLBackendPipeline.cpp | 9 ++++---- libraries/gpu/src/gpu/ResourceSwapChain.h | 19 +++++++---------- .../render-utils/src/AntialiasingEffect.cpp | 21 +++++++++---------- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp index 2285b0e486..d1ab34da90 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp @@ -46,10 +46,10 @@ void GLBackend::do_setFramebuffer(const Batch& batch, size_t paramOffset) { } void GLBackend::do_setFramebufferSwapChain(const Batch& batch, size_t paramOffset) { - auto swapChain = batch._swapChains.get(batch._params[paramOffset]._uint); + auto swapChain = std::static_pointer_cast(batch._swapChains.get(batch._params[paramOffset]._uint)); if (swapChain) { auto index = batch._params[paramOffset + 1]._uint; - FramebufferPointer framebuffer = static_cast(swapChain.get())->get(index); + const auto& framebuffer = swapChain->get(index); setFramebuffer(framebuffer); } } diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp index 237b8bc1e9..d5cb331a4a 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp @@ -1,4 +1,4 @@ -// +// // GLBackendPipeline.cpp // libraries/gpu/src/gpu // @@ -263,7 +263,7 @@ void GLBackend::do_setResourceFramebufferSwapChainTexture(const Batch& batch, si return; } - SwapChainPointer swapChain = batch._swapChains.get(batch._params[paramOffset + 0]._uint); + auto swapChain = std::static_pointer_cast(batch._swapChains.get(batch._params[paramOffset + 0]._uint)); if (!swapChain) { releaseResourceTexture(slot); @@ -271,9 +271,8 @@ void GLBackend::do_setResourceFramebufferSwapChainTexture(const Batch& batch, si } auto index = batch._params[paramOffset + 2]._uint; auto renderBufferSlot = batch._params[paramOffset + 3]._uint; - FramebufferPointer resourceFramebuffer = static_cast(swapChain.get())->get(index); - TexturePointer resourceTexture = resourceFramebuffer->getRenderBuffer(renderBufferSlot); - + auto resourceFramebuffer = swapChain->get(index); + auto resourceTexture = resourceFramebuffer->getRenderBuffer(renderBufferSlot); setResourceTexture(slot, resourceTexture); } diff --git a/libraries/gpu/src/gpu/ResourceSwapChain.h b/libraries/gpu/src/gpu/ResourceSwapChain.h index 7b46b35521..84e8ec7c74 100644 --- a/libraries/gpu/src/gpu/ResourceSwapChain.h +++ b/libraries/gpu/src/gpu/ResourceSwapChain.h @@ -15,18 +15,18 @@ namespace gpu { class SwapChain { public: - SwapChain(unsigned int size = 2U) : _size{ size } {} + SwapChain(size_t size = 2U) : _size{ size } {} virtual ~SwapChain() {} void advance() { _frontIndex = (_frontIndex + 1) % _size; } - unsigned int getSize() const { return _size; } + size_t getSize() const { return _size; } protected: - unsigned int _size; - unsigned int _frontIndex{ 0U }; + const size_t _size; + size_t _frontIndex{ 0U }; }; typedef std::shared_ptr SwapChainPointer; @@ -41,16 +41,13 @@ namespace gpu { using Type = R; using TypePointer = std::shared_ptr; + using TypeConstPointer = std::shared_ptr; - ResourceSwapChain(unsigned int size = 2U) : SwapChain{ size } {} - - void reset() { - for (auto& ptr : _resources) { - ptr.reset(); + ResourceSwapChain(const std::vector& v) : SwapChain{ std::min(v.size(), MAX_SIZE) } { + for (size_t i = 0; i < _size; ++i) { + _resources[i] = v[i]; } } - - TypePointer& edit(unsigned int index) { return _resources[(index + _frontIndex) % _size]; } const TypePointer& get(unsigned int index) const { return _resources[(index + _frontIndex) % _size]; } private: diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index ba5036ad68..357782a321 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -188,7 +188,6 @@ const int AntialiasingPass_NextMapSlot = 4; Antialiasing::Antialiasing() { - _antialiasingBuffers = std::make_shared(2U); } Antialiasing::~Antialiasing() { @@ -317,25 +316,25 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const int width = sourceBuffer->getWidth(); int height = sourceBuffer->getHeight(); - if (_antialiasingBuffers->get(0)) { - if (_antialiasingBuffers->get(0)->getSize() != uvec2(width, height)) {// || (sourceBuffer && (_antialiasingBuffer->getRenderBuffer(1) != sourceBuffer->getRenderBuffer(0)))) { - _antialiasingBuffers->edit(0).reset(); - _antialiasingBuffers->edit(1).reset(); - _antialiasingTextures[0].reset(); - _antialiasingTextures[1].reset(); - } + if (_antialiasingBuffers && _antialiasingBuffers->get(0) && _antialiasingBuffers->get(0)->getSize() != uvec2(width, height)) { + _antialiasingBuffers.reset(); + _antialiasingTextures[0].reset(); + _antialiasingTextures[1].reset(); } - if (!_antialiasingBuffers->get(0)) { + + if (!_antialiasingBuffers) { + std::vector antiAliasingBuffers; // Link the antialiasing FBO to texture for (int i = 0; i < 2; i++) { - auto& antiAliasingBuffer = _antialiasingBuffers->edit(i); - antiAliasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); + antiAliasingBuffers.emplace_back(gpu::Framebuffer::create("antialiasing")); + const auto& antiAliasingBuffer = antiAliasingBuffers.back(); auto format = gpu::Element::COLOR_SRGBA_32; // DependencyManager::get()->getLightingTexture()->getTexelFormat(); auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR); _antialiasingTextures[i] = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); antiAliasingBuffer->setRenderBuffer(0, _antialiasingTextures[i]); } + _antialiasingBuffers = std::make_shared(antiAliasingBuffers); } gpu::doInBatch("Antialiasing::run", args->_context, [&](gpu::Batch& batch) { From fb929da2280ad3a45c32a41130a5ebeeb31e6160 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 1 May 2018 16:54:26 -0700 Subject: [PATCH 027/152] Change type used for swap chain count --- libraries/gpu/src/gpu/ResourceSwapChain.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/gpu/src/gpu/ResourceSwapChain.h b/libraries/gpu/src/gpu/ResourceSwapChain.h index 84e8ec7c74..28c5ff2ed3 100644 --- a/libraries/gpu/src/gpu/ResourceSwapChain.h +++ b/libraries/gpu/src/gpu/ResourceSwapChain.h @@ -15,18 +15,18 @@ namespace gpu { class SwapChain { public: - SwapChain(size_t size = 2U) : _size{ size } {} + SwapChain(uint8_t size = 2U) : _size{ size } {} virtual ~SwapChain() {} void advance() { _frontIndex = (_frontIndex + 1) % _size; } - size_t getSize() const { return _size; } + uint8_t getSize() const { return _size; } protected: - const size_t _size; - size_t _frontIndex{ 0U }; + const uint8_t _size; + uint8_t _frontIndex{ 0U }; }; typedef std::shared_ptr SwapChainPointer; @@ -43,7 +43,7 @@ namespace gpu { using TypePointer = std::shared_ptr; using TypeConstPointer = std::shared_ptr; - ResourceSwapChain(const std::vector& v) : SwapChain{ std::min(v.size(), MAX_SIZE) } { + ResourceSwapChain(const std::vector& v) : SwapChain{ std::min((uint8_t)v.size(), MAX_SIZE) } { for (size_t i = 0; i < _size; ++i) { _resources[i] = v[i]; } From 93afbcdc08f42f68e4c0f9417279bd012f69643f Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 1 May 2018 17:59:07 -0700 Subject: [PATCH 028/152] First success with running from command line. --- tools/auto-tester/src/Test.cpp | 53 ++++++++++++++----------- tools/auto-tester/src/Test.h | 29 +++++++------- tools/auto-tester/src/main.cpp | 15 ++++++- tools/auto-tester/src/ui/AutoTester.cpp | 12 ++++-- tools/auto-tester/src/ui/AutoTester.h | 5 +++ 5 files changed, 70 insertions(+), 44 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index d0a1606cd8..7139f0a43c 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -27,7 +27,7 @@ Test::Test() { mismatchWindow.setModal(true); } -bool Test::createTestResultsFolderPath(QString directory) { +bool Test::createTestResultsFolderPath(const QString& directory) { QDateTime now = QDateTime::currentDateTime(); testResultsFolderPath = directory + "/" + TEST_RESULTS_FOLDER + "--" + now.toString(DATETIME_FORMAT); QDir testResultsFolder(testResultsFolderPath); @@ -125,7 +125,7 @@ bool Test::compareImageLists(bool isInteractiveMode, QProgressBar* progressBar) return success; } -void Test::appendTestResultsToFile(QString testResultsFolderPath, TestFailure testFailure, QPixmap comparisonImage) { +void Test::appendTestResultsToFile(const QString& testResultsFolderPath, TestFailure testFailure, QPixmap comparisonImage) { if (!QDir().exists(testResultsFolderPath)) { messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Folder " + testResultsFolderPath + " not found"); exit(-1); @@ -174,10 +174,16 @@ void Test::appendTestResultsToFile(QString testResultsFolderPath, TestFailure te comparisonImage.save(failureFolderPath + "/" + "Difference Image.jpg"); } -void Test::startTestsEvaluation() { - // Get list of JPEG images in folder, sorted by name - pathToTestResultsDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", ".", QFileDialog::ShowDirsOnly); - if (pathToTestResultsDirectory == "") { +void Test::startTestsEvaluation(const QString& testFolder) { + QString pathToTestResultsDirectory; + if (testFolder.isNull()) { + // Get list of JPEG images in folder, sorted by name + pathToTestResultsDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", ".", QFileDialog::ShowDirsOnly); + } else { + pathToTestResultsDirectory = testFolder; + } + + if (pathToTestResultsDirectory == QString()) { return; } @@ -221,9 +227,6 @@ void Test::startTestsEvaluation() { QString expectedImageFilenameTail = currentFilename.left(currentFilename.length() - 4).right(NUM_DIGITS); QString expectedImageStoredFilename = EXPECTED_IMAGE_PREFIX + expectedImageFilenameTail + ".png"; - //https://raw.githubusercontent.com/highfidelity/hifi_tests/master/tests/content/entity/zone/zoneOrientation/ExpectedImage_00001.png - - QString imageURLString("https://raw.githubusercontent.com/" + githubUser + "/hifi_tests/" + gitHubBranch + "/" + expectedImagePartialSourceDirectory + "/" + expectedImageStoredFilename); @@ -240,19 +243,21 @@ void Test::startTestsEvaluation() { autoTester->downloadImages(expectedImagesURLs, pathToTestResultsDirectory, expectedImagesFilenames); } -void Test::finishTestsEvaluation(bool interactiveMode, QProgressBar* progressBar) { - bool success = compareImageLists(interactiveMode, progressBar); +void Test::finishTestsEvaluation(bool isRunningFromCommandline, bool interactiveMode, QProgressBar* progressBar) { + bool success = compareImageLists((!isRunningFromCommandline && interactiveMode), progressBar); - if (success) { - messageBox.information(0, "Success", "All images are as expected"); - } else { - messageBox.information(0, "Failure", "One or more images are not as expected"); + if (!isRunningFromCommandline) { + if (success) { + messageBox.information(0, "Success", "All images are as expected"); + } else { + messageBox.information(0, "Failure", "One or more images are not as expected"); + } } zipAndDeleteTestResultsFolder(); } -bool Test::isAValidDirectory(QString pathname) { +bool Test::isAValidDirectory(const QString& pathname) { // Only process directories QDir dir(pathname); if (!dir.exists()) { @@ -267,7 +272,7 @@ bool Test::isAValidDirectory(QString pathname) { return true; } -QString Test::extractPathFromTestsDown(QString fullPath) { +QString Test::extractPathFromTestsDown(const QString& fullPath) { // `fullPath` includes the full path to the test. We need the portion below (and including) `tests` QStringList pathParts = fullPath.split('/'); int i{ 0 }; @@ -348,7 +353,7 @@ void Test::createAllRecursiveScripts() { messageBox.information(0, "Success", "Scripts have been created"); } -void Test::createRecursiveScript(QString topLevelDirectory, bool interactiveMode) { +void Test::createRecursiveScript(const QString& topLevelDirectory, bool interactiveMode) { const QString recursiveTestsFilename("testRecursive.js"); QFile allTestsFilename(topLevelDirectory + "/" + recursiveTestsFilename); if (!allTestsFilename.open(QIODevice::WriteOnly | QIODevice::Text)) { @@ -615,7 +620,7 @@ void Test::createAllMDFiles() { messageBox.information(0, "Success", "MD files have been created"); } -void Test::createMDFile(QString testDirectory) { +void Test::createMDFile(const QString& testDirectory) { // Verify folder contains test.js file QString testFileName(testDirectory + "/" + TEST_FILENAME); QFileInfo testFileInfo(testFileName); @@ -790,7 +795,7 @@ void Test::createTestsOutline() { messageBox.information(0, "Success", "Test outline file " + testsOutlineFilename + " has been created"); } -void Test::copyJPGtoPNG(QString sourceJPGFullFilename, QString destinationPNGFullFilename) { +void Test::copyJPGtoPNG(const QString& sourceJPGFullFilename, const QString& destinationPNGFullFilename) { QFile::remove(destinationPNGFullFilename); QImageReader reader; @@ -803,7 +808,7 @@ void Test::copyJPGtoPNG(QString sourceJPGFullFilename, QString destinationPNGFul writer.write(image); } -QStringList Test::createListOfAll_imagesInDirectory(QString imageFormat, QString pathToImageDirectory) { +QStringList Test::createListOfAll_imagesInDirectory(const QString& imageFormat, const QString& pathToImageDirectory) { imageDirectory = QDir(pathToImageDirectory); QStringList nameFilters; nameFilters << "*." + imageFormat; @@ -816,7 +821,7 @@ QStringList Test::createListOfAll_imagesInDirectory(QString imageFormat, QString // Filename (i.e. without extension) contains _tests_ (this is based on all test scripts being within the tests folder // Last 5 characters in filename are digits // Extension is jpg -bool Test::isInSnapshotFilenameFormat(QString imageFormat, QString filename) { +bool Test::isInSnapshotFilenameFormat(const QString& imageFormat, const QString& filename) { QStringList filenameParts = filename.split("."); bool filnameHasNoPeriods = (filenameParts.size() == 2); @@ -833,7 +838,7 @@ bool Test::isInSnapshotFilenameFormat(QString imageFormat, QString filename) { // For a file named "D_GitHub_hifi-tests_tests_content_entity_zone_create_0.jpg", the test directory is // D:/GitHub/hifi-tests/tests/content/entity/zone/create // This method assumes the filename is in the correct format -QString Test::getExpectedImageDestinationDirectory(QString filename) { +QString Test::getExpectedImageDestinationDirectory(const QString& filename) { QString filenameWithoutExtension = filename.split(".")[0]; QStringList filenameParts = filenameWithoutExtension.split("_"); @@ -850,7 +855,7 @@ QString Test::getExpectedImageDestinationDirectory(QString filename) { // is ...tests/content/entity/zone/create // This is used to create the full URL // This method assumes the filename is in the correct format -QString Test::getExpectedImagePartialSourceDirectory(QString filename) { +QString Test::getExpectedImagePartialSourceDirectory(const QString& filename) { QString filenameWithoutExtension = filename.split(".")[0]; QStringList filenameParts = filenameWithoutExtension.split("_"); diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index 7f5553f9e3..02cab53381 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -43,39 +43,39 @@ class Test { public: Test(); - void startTestsEvaluation(); - void finishTestsEvaluation(bool interactiveMode, QProgressBar* progressBar); + void startTestsEvaluation(const QString& testFolder = QString()); + void finishTestsEvaluation(bool isRunningFromCommandline, bool interactiveMode, QProgressBar* progressBar); void createRecursiveScript(); void createAllRecursiveScripts(); - void createRecursiveScript(QString topLevelDirectory, bool interactiveMode); + void createRecursiveScript(const QString& topLevelDirectory, bool interactiveMode); void createTest(); void createMDFile(); void createAllMDFiles(); - void createMDFile(QString topLevelDirectory); + void createMDFile(const QString& topLevelDirectory); void createTestsOutline(); bool compareImageLists(bool isInteractiveMode, QProgressBar* progressBar); - QStringList createListOfAll_imagesInDirectory(QString imageFormat, QString pathToImageDirectory); + QStringList createListOfAll_imagesInDirectory(const QString& imageFormat, const QString& pathToImageDirectory); - bool isInSnapshotFilenameFormat(QString imageFormat, QString filename); + bool isInSnapshotFilenameFormat(const QString& imageFormat, const QString& filename); void importTest(QTextStream& textStream, const QString& testPathname); - void appendTestResultsToFile(QString testResultsFolderPath, TestFailure testFailure, QPixmap comparisonImage); + void appendTestResultsToFile(const QString& testResultsFolderPath, TestFailure testFailure, QPixmap comparisonImage); - bool createTestResultsFolderPath(QString directory); + bool createTestResultsFolderPath(const QString& directory); void zipAndDeleteTestResultsFolder(); - bool isAValidDirectory(QString pathname); - QString extractPathFromTestsDown(QString fullPath); - QString getExpectedImageDestinationDirectory(QString filename); - QString getExpectedImagePartialSourceDirectory(QString filename); + bool isAValidDirectory(const QString& pathname); + QString extractPathFromTestsDown(const QString& fullPath); + QString getExpectedImageDestinationDirectory(const QString& filename); + QString getExpectedImagePartialSourceDirectory(const QString& filename); - void copyJPGtoPNG(QString sourceJPGFullFilename, QString destinationPNGFullFilename); + void copyJPGtoPNG(const QString& sourceJPGFullFilename, const QString& destinationPNGFullFilename); private: const QString TEST_FILENAME { "test.js" }; @@ -90,14 +90,13 @@ private: ImageComparer imageComparer; - QString testResultsFolderPath { "" }; + QString testResultsFolderPath; int index { 1 }; // Expected images are in the format ExpectedImage_dddd.jpg (d == decimal digit) const int NUM_DIGITS { 5 }; const QString EXPECTED_IMAGE_PREFIX { "ExpectedImage_" }; - QString pathToTestResultsDirectory; QStringList expectedImagesFilenames; QStringList expectedImagesFullFilenames; QStringList resultImagesFullFilenames; diff --git a/tools/auto-tester/src/main.cpp b/tools/auto-tester/src/main.cpp index cd0ce22b13..ffa7a0b237 100644 --- a/tools/auto-tester/src/main.cpp +++ b/tools/auto-tester/src/main.cpp @@ -13,10 +13,23 @@ AutoTester* autoTester; int main(int argc, char *argv[]) { + // Only parameter is "--testFolder" + QString testFolder; + if (argc == 3) { + if (QString(argv[1]) == "--testFolder") { + testFolder = QString(argv[2]); + } + } + QApplication application(argc, argv); autoTester = new AutoTester(); - autoTester->show(); + + if (!testFolder.isNull()) { + autoTester->runFromCommandLine(testFolder); + } else { + autoTester->show(); + } return application.exec(); } diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index 17b1513467..e0f92664ef 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -15,12 +15,17 @@ AutoTester::AutoTester(QWidget *parent) : QMainWindow(parent) { ui.checkBoxInteractiveMode->setChecked(true); ui.progressBar->setVisible(false); - test = new Test(); - signalMapper = new QSignalMapper(); connect(ui.actionClose, &QAction::triggered, this, &AutoTester::on_closeButton_clicked); connect(ui.actionAbout, &QAction::triggered, this, &AutoTester::about); + + test = new Test(); +} + +void AutoTester::runFromCommandLine(const QString& testFolder) { + isRunningFromCommandline = true; + test->startTestsEvaluation(testFolder); } void AutoTester::on_evaluateTestsButton_clicked() { @@ -86,7 +91,6 @@ void AutoTester::downloadImages(const QStringList& URLs, const QString& director } void AutoTester::saveImage(int index) { - QByteArray q = downloaders[index]->downloadedData(); QPixmap pixmap; pixmap.loadFromData(downloaders[index]->downloadedData()); @@ -105,7 +109,7 @@ void AutoTester::saveImage(int index) { ++_numberOfImagesDownloaded; if (_numberOfImagesDownloaded == _numberOfImagesToDownload) { - test->finishTestsEvaluation(ui.checkBoxInteractiveMode->isChecked(), ui.progressBar); + test->finishTestsEvaluation(isRunningFromCommandline, ui.checkBoxInteractiveMode->isChecked(), ui.progressBar); } else { ui.progressBar->setValue(_numberOfImagesDownloaded); } diff --git a/tools/auto-tester/src/ui/AutoTester.h b/tools/auto-tester/src/ui/AutoTester.h index d911b6aaff..fe37f2298d 100644 --- a/tools/auto-tester/src/ui/AutoTester.h +++ b/tools/auto-tester/src/ui/AutoTester.h @@ -22,6 +22,9 @@ class AutoTester : public QMainWindow { public: AutoTester(QWidget *parent = Q_NULLPTR); + + void runFromCommandLine(const QString& testFolder); + void downloadImage(const QUrl& url); void downloadImages(const QStringList& URLs, const QString& directoryName, const QStringList& filenames); @@ -55,6 +58,8 @@ private: int _numberOfImagesToDownload { 0 }; int _numberOfImagesDownloaded { 0 }; int _index { 0 }; + + bool isRunningFromCommandline { false }; }; #endif // hifi_AutoTester_h \ No newline at end of file From 7bad849e67e4ff2ccefb90f3d1c149b06eedacfb Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 1 May 2018 15:29:22 -0700 Subject: [PATCH 029/152] Make resource swapchains immutable, fix for 14638 --- .../src/gpu/gl/GLBackendOutput.cpp | 4 ++-- .../src/gpu/gl/GLBackendPipeline.cpp | 7 +++---- libraries/gpu/src/gpu/ResourceSwapChain.h | 19 +++++++---------- .../render-utils/src/AntialiasingEffect.cpp | 21 +++++++++---------- 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp index 2285b0e486..d1ab34da90 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendOutput.cpp @@ -46,10 +46,10 @@ void GLBackend::do_setFramebuffer(const Batch& batch, size_t paramOffset) { } void GLBackend::do_setFramebufferSwapChain(const Batch& batch, size_t paramOffset) { - auto swapChain = batch._swapChains.get(batch._params[paramOffset]._uint); + auto swapChain = std::static_pointer_cast(batch._swapChains.get(batch._params[paramOffset]._uint)); if (swapChain) { auto index = batch._params[paramOffset + 1]._uint; - FramebufferPointer framebuffer = static_cast(swapChain.get())->get(index); + const auto& framebuffer = swapChain->get(index); setFramebuffer(framebuffer); } } diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp index 58fcc51605..91f1d8bb8c 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp @@ -268,7 +268,7 @@ void GLBackend::do_setResourceFramebufferSwapChainTexture(const Batch& batch, si return; } - SwapChainPointer swapChain = batch._swapChains.get(batch._params[paramOffset + 0]._uint); + auto swapChain = std::static_pointer_cast(batch._swapChains.get(batch._params[paramOffset + 0]._uint)); if (!swapChain) { releaseResourceTexture(slot); @@ -276,9 +276,8 @@ void GLBackend::do_setResourceFramebufferSwapChainTexture(const Batch& batch, si } auto index = batch._params[paramOffset + 2]._uint; auto renderBufferSlot = batch._params[paramOffset + 3]._uint; - FramebufferPointer resourceFramebuffer = static_cast(swapChain.get())->get(index); - TexturePointer resourceTexture = resourceFramebuffer->getRenderBuffer(renderBufferSlot); - + auto resourceFramebuffer = swapChain->get(index); + auto resourceTexture = resourceFramebuffer->getRenderBuffer(renderBufferSlot); setResourceTexture(slot, resourceTexture); } diff --git a/libraries/gpu/src/gpu/ResourceSwapChain.h b/libraries/gpu/src/gpu/ResourceSwapChain.h index 7b46b35521..84e8ec7c74 100644 --- a/libraries/gpu/src/gpu/ResourceSwapChain.h +++ b/libraries/gpu/src/gpu/ResourceSwapChain.h @@ -15,18 +15,18 @@ namespace gpu { class SwapChain { public: - SwapChain(unsigned int size = 2U) : _size{ size } {} + SwapChain(size_t size = 2U) : _size{ size } {} virtual ~SwapChain() {} void advance() { _frontIndex = (_frontIndex + 1) % _size; } - unsigned int getSize() const { return _size; } + size_t getSize() const { return _size; } protected: - unsigned int _size; - unsigned int _frontIndex{ 0U }; + const size_t _size; + size_t _frontIndex{ 0U }; }; typedef std::shared_ptr SwapChainPointer; @@ -41,16 +41,13 @@ namespace gpu { using Type = R; using TypePointer = std::shared_ptr; + using TypeConstPointer = std::shared_ptr; - ResourceSwapChain(unsigned int size = 2U) : SwapChain{ size } {} - - void reset() { - for (auto& ptr : _resources) { - ptr.reset(); + ResourceSwapChain(const std::vector& v) : SwapChain{ std::min(v.size(), MAX_SIZE) } { + for (size_t i = 0; i < _size; ++i) { + _resources[i] = v[i]; } } - - TypePointer& edit(unsigned int index) { return _resources[(index + _frontIndex) % _size]; } const TypePointer& get(unsigned int index) const { return _resources[(index + _frontIndex) % _size]; } private: diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index e620fc2d61..f77b4fc68b 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -189,7 +189,6 @@ const int AntialiasingPass_NextMapSlot = 4; Antialiasing::Antialiasing(bool isSharpenEnabled) : _isSharpenEnabled{ isSharpenEnabled } { - _antialiasingBuffers = std::make_shared(2U); } Antialiasing::~Antialiasing() { @@ -321,25 +320,25 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const int width = sourceBuffer->getWidth(); int height = sourceBuffer->getHeight(); - if (_antialiasingBuffers->get(0)) { - if (_antialiasingBuffers->get(0)->getSize() != uvec2(width, height)) {// || (sourceBuffer && (_antialiasingBuffer->getRenderBuffer(1) != sourceBuffer->getRenderBuffer(0)))) { - _antialiasingBuffers->edit(0).reset(); - _antialiasingBuffers->edit(1).reset(); - _antialiasingTextures[0].reset(); - _antialiasingTextures[1].reset(); - } + if (_antialiasingBuffers && _antialiasingBuffers->get(0) && _antialiasingBuffers->get(0)->getSize() != uvec2(width, height)) { + _antialiasingBuffers.reset(); + _antialiasingTextures[0].reset(); + _antialiasingTextures[1].reset(); } - if (!_antialiasingBuffers->get(0)) { + + if (!_antialiasingBuffers) { + std::vector antiAliasingBuffers; // Link the antialiasing FBO to texture auto format = sourceBuffer->getRenderBuffer(0)->getTexelFormat(); auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP); for (int i = 0; i < 2; i++) { - auto& antiAliasingBuffer = _antialiasingBuffers->edit(i); - antiAliasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); + antiAliasingBuffers.emplace_back(gpu::Framebuffer::create("antialiasing")); + const auto& antiAliasingBuffer = antiAliasingBuffers.back(); _antialiasingTextures[i] = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); antiAliasingBuffer->setRenderBuffer(0, _antialiasingTextures[i]); } + _antialiasingBuffers = std::make_shared(antiAliasingBuffers); } gpu::doInBatch("Antialiasing::run", args->_context, [&](gpu::Batch& batch) { From 233c60a5063573cb55770b382013deeefadfba6f Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 1 May 2018 16:54:26 -0700 Subject: [PATCH 030/152] Change type used for swap chain count --- libraries/gpu/src/gpu/ResourceSwapChain.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/gpu/src/gpu/ResourceSwapChain.h b/libraries/gpu/src/gpu/ResourceSwapChain.h index 84e8ec7c74..28c5ff2ed3 100644 --- a/libraries/gpu/src/gpu/ResourceSwapChain.h +++ b/libraries/gpu/src/gpu/ResourceSwapChain.h @@ -15,18 +15,18 @@ namespace gpu { class SwapChain { public: - SwapChain(size_t size = 2U) : _size{ size } {} + SwapChain(uint8_t size = 2U) : _size{ size } {} virtual ~SwapChain() {} void advance() { _frontIndex = (_frontIndex + 1) % _size; } - size_t getSize() const { return _size; } + uint8_t getSize() const { return _size; } protected: - const size_t _size; - size_t _frontIndex{ 0U }; + const uint8_t _size; + uint8_t _frontIndex{ 0U }; }; typedef std::shared_ptr SwapChainPointer; @@ -43,7 +43,7 @@ namespace gpu { using TypePointer = std::shared_ptr; using TypeConstPointer = std::shared_ptr; - ResourceSwapChain(const std::vector& v) : SwapChain{ std::min(v.size(), MAX_SIZE) } { + ResourceSwapChain(const std::vector& v) : SwapChain{ std::min((uint8_t)v.size(), MAX_SIZE) } { for (size_t i = 0; i < _size; ++i) { _resources[i] = v[i]; } From e0b16dfe03493caf8f8aae8cbe02393b21d66df5 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Wed, 2 May 2018 14:17:01 -0700 Subject: [PATCH 031/152] Allow use of `--url` command line argument in test mode. --- interface/src/Application.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eb59576cc0..3c9e244da6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2143,6 +2143,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto scriptEngines = DependencyManager::get(); const auto testScript = property(hifi::properties::TEST).toUrl(); scriptEngines->loadScript(testScript, false); + + // This is done so we don't get a "connection time-out" message when we haven't passed in a URL. + if (arguments().contains("--url")) { + auto reply = SandboxUtils::getStatus(); + connect(reply, &QNetworkReply::finished, this, [=] { + handleSandboxStatus(reply); + }); + } } else { PROFILE_RANGE(render, "GetSandboxStatus"); auto reply = SandboxUtils::getStatus(); From 5cbb8674ec2c001302cdcc43085b2ea7cf62157c Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Wed, 2 May 2018 14:45:28 -0700 Subject: [PATCH 032/152] Use default parameter for saveSnapshot(). --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 2 +- interface/src/ui/Snapshot.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 22a77b9bf1..bd306948bb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7387,7 +7387,7 @@ void Application::loadAvatarBrowser() const { void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) { postLambdaEvent([notify, includeAnimated, aspectRatio, filename, this] { // Get a screenshot and save it - QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, QString()); + QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename); // If we're not doing an animated snapshot as well... if (!includeAnimated) { // Tell the dependency manager that the capture of the still snapshot has taken place. diff --git a/interface/src/Application.h b/interface/src/Application.h index f1276bca34..fe31f55dcb 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -732,6 +732,6 @@ private: std::atomic _pendingIdleEvent { true }; std::atomic _pendingRenderEvent { true }; - QString testSnapshotLocation { QString() }; + QString testSnapshotLocation; }; #endif // hifi_Application_h diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index 86c860cfcb..a3454bcba5 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -37,7 +37,7 @@ class Snapshot : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY public: - static QString saveSnapshot(QImage image, const QString& filename, const QString& pathname); + static QString saveSnapshot(QImage image, const QString& filename, const QString& pathname = QString()); static QTemporaryFile* saveTempSnapshot(QImage image); static SnapshotMetaData* parseSnapshotData(QString snapshotPath); From 56e5b0e7b434c6375207c0f4cf14fbaea03666cb Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Wed, 2 May 2018 15:25:31 -0700 Subject: [PATCH 033/152] Added `autoTester.enableAuto();` to the recursive tests. --- tools/auto-tester/src/Test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index 7139f0a43c..18d1350402 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -371,7 +371,8 @@ void Test::createRecursiveScript(const QString& topLevelDirectory, bool interact textStream << "var autoTester = Script.require(\"https://github.com/" + githubUser + "/hifi_tests/blob/" + gitHubBranch + "/tests/utils/autoTester.js?raw=true\");" << endl; - textStream << "autoTester.enableRecursive();" << endl << endl; + textStream << "autoTester.enableRecursive();" << endl; + textStream << "autoTester.enableAuto();" << endl << endl; QVector testPathnames; From b9cdaf31a07b0346aa5e3a1005c106687097e1ef Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Wed, 2 May 2018 15:26:03 -0700 Subject: [PATCH 034/152] Corrected name of create all recursive tests call. --- tools/auto-tester/src/ui/AutoTester.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/auto-tester/src/ui/AutoTester.ui b/tools/auto-tester/src/ui/AutoTester.ui index c5115d69b2..8c534eb7c7 100644 --- a/tools/auto-tester/src/ui/AutoTester.ui +++ b/tools/auto-tester/src/ui/AutoTester.ui @@ -95,7 +95,7 @@ 24 - + 360 From 9776e1d15d42313d845ac532a4c77d807c1ae9fa Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 2 May 2018 23:38:30 -0700 Subject: [PATCH 035/152] Exposing larger number of ubo because we can and moving the ubo slot using 11 to 12 to avoid collision --- .../src/RenderableParticleEffectEntityItem.cpp | 4 ++-- .../entities-renderer/src/RenderablePolyLineEntityItem.cpp | 4 ++-- libraries/gpu-gl-common/src/gpu/gl/GLBackend.h | 2 +- libraries/gpu/src/gpu/Batch.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index b3a4a1a1ab..ee77646920 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -23,8 +23,8 @@ using namespace render::entities; static uint8_t CUSTOM_PIPELINE_NUMBER = 0; static gpu::Stream::FormatPointer _vertexFormat; static std::weak_ptr _texturedPipeline; -// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 11 to avoid collisions -static int32_t PARTICLE_UNIFORM_SLOT { 11 }; +// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 12 to avoid collisions +static int32_t PARTICLE_UNIFORM_SLOT { 12 }; static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, gpu::Batch& batch) { auto texturedPipeline = _texturedPipeline.lock(); diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 394ab08dfb..d571eac35c 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -34,8 +34,8 @@ using namespace render::entities; static uint8_t CUSTOM_PIPELINE_NUMBER { 0 }; static const int32_t PAINTSTROKE_TEXTURE_SLOT { 0 }; -// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 11 to avoid collisions -static const int32_t PAINTSTROKE_UNIFORM_SLOT { 11 }; +// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 12 to avoid collisions +static const int32_t PAINTSTROKE_UNIFORM_SLOT { 12 }; static gpu::Stream::FormatPointer polylineFormat; static gpu::PipelinePointer polylinePipeline; #ifdef POLYLINE_ENTITY_USE_FADE_EFFECT diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index f2e2271552..53a147fb27 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -92,7 +92,7 @@ public: // this is the maximum per shader stage on the low end apple // TODO make it platform dependant at init time - static const int MAX_NUM_UNIFORM_BUFFERS = 12; + static const int MAX_NUM_UNIFORM_BUFFERS = 15; size_t getMaxNumUniformBuffers() const { return MAX_NUM_UNIFORM_BUFFERS; } // this is the maximum per shader stage on the low end apple diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 31bbfdd708..7725ee7bce 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -34,7 +34,7 @@ ProfileRangeBatch::~ProfileRangeBatch() { using namespace gpu; // FIXME make these backend / pipeline dependent. -static const int MAX_NUM_UNIFORM_BUFFERS = 12; +static const int MAX_NUM_UNIFORM_BUFFERS = 15; static const int MAX_NUM_RESOURCE_BUFFERS = 16; static const int MAX_NUM_RESOURCE_TEXTURES = 16; From 6579e3c3d23a9117e7f64bcc4a320bebf3498c7b Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 3 May 2018 09:09:58 -0700 Subject: [PATCH 036/152] Adjusting the number to 14 max UBO per shader stage after checking on opengl.glinfo.org --- libraries/gpu-gl-common/src/gpu/gl/GLBackend.h | 2 +- libraries/gpu/src/gpu/Batch.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 53a147fb27..f0b79fb23e 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -92,7 +92,7 @@ public: // this is the maximum per shader stage on the low end apple // TODO make it platform dependant at init time - static const int MAX_NUM_UNIFORM_BUFFERS = 15; + static const int MAX_NUM_UNIFORM_BUFFERS = 14; size_t getMaxNumUniformBuffers() const { return MAX_NUM_UNIFORM_BUFFERS; } // this is the maximum per shader stage on the low end apple diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 7725ee7bce..4b965af7bc 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -34,7 +34,7 @@ ProfileRangeBatch::~ProfileRangeBatch() { using namespace gpu; // FIXME make these backend / pipeline dependent. -static const int MAX_NUM_UNIFORM_BUFFERS = 15; +static const int MAX_NUM_UNIFORM_BUFFERS = 14; static const int MAX_NUM_RESOURCE_BUFFERS = 16; static const int MAX_NUM_RESOURCE_TEXTURES = 16; From 60a49c3f7c630f03666e04cc67f3c4558c7816cf Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 3 May 2018 10:37:29 -0700 Subject: [PATCH 037/152] applying the local lights on translucent fix --- .../src/RenderableParticleEffectEntityItem.cpp | 4 ++-- .../entities-renderer/src/RenderablePolyLineEntityItem.cpp | 4 ++-- libraries/gpu-gl-common/src/gpu/gl/GLBackend.h | 2 +- libraries/gpu/src/gpu/Batch.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index b3a4a1a1ab..ee77646920 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -23,8 +23,8 @@ using namespace render::entities; static uint8_t CUSTOM_PIPELINE_NUMBER = 0; static gpu::Stream::FormatPointer _vertexFormat; static std::weak_ptr _texturedPipeline; -// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 11 to avoid collisions -static int32_t PARTICLE_UNIFORM_SLOT { 11 }; +// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 12 to avoid collisions +static int32_t PARTICLE_UNIFORM_SLOT { 12 }; static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, gpu::Batch& batch) { auto texturedPipeline = _texturedPipeline.lock(); diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 394ab08dfb..d571eac35c 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -34,8 +34,8 @@ using namespace render::entities; static uint8_t CUSTOM_PIPELINE_NUMBER { 0 }; static const int32_t PAINTSTROKE_TEXTURE_SLOT { 0 }; -// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 11 to avoid collisions -static const int32_t PAINTSTROKE_UNIFORM_SLOT { 11 }; +// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 12 to avoid collisions +static const int32_t PAINTSTROKE_UNIFORM_SLOT { 12 }; static gpu::Stream::FormatPointer polylineFormat; static gpu::PipelinePointer polylinePipeline; #ifdef POLYLINE_ENTITY_USE_FADE_EFFECT diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 5bbb44f9e1..314bbee387 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -91,7 +91,7 @@ public: // this is the maximum per shader stage on the low end apple // TODO make it platform dependant at init time - static const int MAX_NUM_UNIFORM_BUFFERS = 12; + static const int MAX_NUM_UNIFORM_BUFFERS = 14; size_t getMaxNumUniformBuffers() const { return MAX_NUM_UNIFORM_BUFFERS; } // this is the maximum per shader stage on the low end apple diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 84a7c275f0..90115806b4 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -34,7 +34,7 @@ ProfileRangeBatch::~ProfileRangeBatch() { using namespace gpu; // FIXME make these backend / pipeline dependent. -static const int MAX_NUM_UNIFORM_BUFFERS = 12; +static const int MAX_NUM_UNIFORM_BUFFERS = 14; static const int MAX_NUM_RESOURCE_BUFFERS = 16; static const int MAX_NUM_RESOURCE_TEXTURES = 16; From 46f461dcdbdcf40095ef4e152fc082ae27d952e3 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 11:20:37 -0700 Subject: [PATCH 038/152] Don't display crash message if running from command line with a test script. --- interface/src/Application.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2abac520fb..45a1a34f1a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -743,6 +743,9 @@ extern DisplayPluginList getDisplayPlugins(); extern InputPluginList getInputPlugins(); extern void saveInputPluginSettings(const InputPluginList& plugins); +const QString TEST_SCRIPT { "--testScript" }; +const QString TEST_SNAPSHOT_LOCATION { "--testSnapshotLocation" }; + bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { const char** constArgv = const_cast(argv); @@ -777,7 +780,22 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset"; bool suppressPrompt = cmdOptionExists(argc, const_cast(argv), SUPPRESS_SETTINGS_RESET); - bool previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt); + + // Ignore any previous crashes if running from command line with a test script. + bool inTestMode { false }; + for (int i = 0; i < argc; ++i) { + QString parameter(argv[i]); + if (parameter == TEST_SCRIPT) { + inTestMode = true; + break; + } + } + + bool previousSessionCrashed { false }; + if (!inTestMode) { + previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt); + } + // get dir to use for cache static const auto CACHE_SWITCH = "--cache"; QString cacheDir = getCmdOption(argc, const_cast(argv), CACHE_SWITCH); @@ -997,10 +1015,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning())); setProperty(hifi::properties::CRASHED, _previousSessionCrashed); { - const QString TEST_SCRIPT { "--testScript" }; - const QString TEST_SNAPSHOT_LOCATION { "--testSnapshotLocation" }; - const QStringList args = arguments(); + for (int i = 0; i < args.size() - 1; ++i) { if (args.at(i) == TEST_SCRIPT) { QString testScriptPath = args.at(i + 1); From 4793cddde6a4e1eb12281df57b0cb722e9e66f68 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 3 May 2018 11:27:07 -0700 Subject: [PATCH 039/152] fix highlighting issues --- .../highlightNearbyEntities.js | 4 ++- .../mouseHighlightEntities.js | 31 +++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index a66f7bd144..32e1b4300d 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -89,7 +89,9 @@ } if (this.isGrabable(controllerData, props) || this.hasHyperLink(props)) { dispatcherUtils.highlightTargetEntity(props.id); - newHighlightedEntities.push(props.id); + if (newHighlightedEntities.indexOf(props.id) < 0) { + newHighlightedEntities.push(props.id); + } } } diff --git a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js index 6af1055a69..86c96fcf6b 100644 --- a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js +++ b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js @@ -12,7 +12,7 @@ /* jslint bitwise: true */ -/* global Script, print, Entities, Picks, HMD */ +/* global Script, print, Entities, Picks, HMD, Controller, MyAvatar*/ (function() { @@ -20,6 +20,7 @@ function MouseHighlightEntities() { this.highlightedEntity = null; + this.grabbedEntity = null; this.parameters = dispatcherUtils.makeDispatcherModuleParameters( 5, @@ -27,13 +28,18 @@ [], 100); + this.setGrabbedEntity = function(entity) { + this.grabbedEntity = entity; + this.highlightedEntity = null; + }; + this.isReady = function(controllerData) { if (HMD.active) { if (this.highlightedEntity) { dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity); this.highlightedEntity = null; } - } else { + } else if (!this.grabbedEntity) { var pickResult = controllerData.mouseRayPick; if (pickResult.type === Picks.INTERSECTED_ENTITY) { var targetEntityID = pickResult.objectID; @@ -70,8 +76,29 @@ var mouseHighlightEntities = new MouseHighlightEntities(); dispatcherUtils.enableDispatcherModule("MouseHighlightEntities", mouseHighlightEntities); + var handleMessage = function(channel, message, sender) { + var data; + if (sender === MyAvatar.sessionUUID) { + if (channel === 'Hifi-Object-Manipulation') { + try { + data = JSON.parse(message); + if (data.action === 'grab') { + var grabbedEntity = data.grabbedEntity; + mouseHighlightEntities.setGrabbedEntity(grabbedEntity); + } else if (data.action === 'release') { + mouseHighlightEntities.setGrabbedEntity(null); + } + } catch (e) { + print("Warning: mouseHighlightEntities -- error parsing Hifi-Object-Manipulation: " + message); + } + } + } + }; + function cleanup() { dispatcherUtils.disableDispatcherModule("MouseHighlightEntities"); } + Messages.subscribe('Hifi-Object-Manipulation'); + Messages.messageReceived.connect(handleMessage); Script.scriptEnding.connect(cleanup); })(); From cffb008c3113b3871533d0e4b4aa1448dd99b604 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 3 May 2018 13:07:32 -0700 Subject: [PATCH 040/152] fixing edge case --- scripts/system/controllers/grab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index 8ae94a4caa..a835373e4d 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -409,7 +409,7 @@ Grabber.prototype.pressEvent = function(event) { var args = "mouse"; Entities.callEntityMethod(this.entityID, "startDistanceGrab", args); - Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ + Messages.sendLocalMessage('Hifi-Object-Manipulation', JSON.stringify({ action: 'grab', grabbedEntity: this.entityID })); @@ -450,7 +450,7 @@ Grabber.prototype.releaseEvent = function(event) { var args = "mouse"; Entities.callEntityMethod(this.entityID, "releaseGrab", args); - Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ + Messages.sendLocalMessage('Hifi-Object-Manipulation', JSON.stringify({ action: 'release', grabbedEntity: this.entityID, joint: "mouse" From 3a5425122bcba2a91525c457ef92ca752a4dd782 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 14:31:01 -0700 Subject: [PATCH 041/152] Shutdown interface when test script finishes. --- interface/src/Application.cpp | 4 +++- libraries/script-engine/src/ScriptEngines.cpp | 11 ++++++++++- libraries/script-engine/src/ScriptEngines.h | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 45a1a34f1a..d8c162a79c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2160,7 +2160,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (testProperty.isValid()) { auto scriptEngines = DependencyManager::get(); const auto testScript = property(hifi::properties::TEST).toUrl(); - scriptEngines->loadScript(testScript, false); + + // Set last parameter to exit interface when the test script finishes + scriptEngines->loadScript(testScript, false, false, false, false, true); // This is done so we don't get a "connection time-out" message when we haven't passed in a URL. if (arguments().contains("--url")) { diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index f2ed296b63..ef4eddbf39 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -456,7 +456,7 @@ void ScriptEngines::reloadAllScripts() { } ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor, - bool activateMainWindow, bool reload) { + bool activateMainWindow, bool reload, bool exitWhenFinished) { if (thread() != QThread::currentThread()) { ScriptEnginePointer result { nullptr }; BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(ScriptEnginePointer, result), @@ -496,6 +496,11 @@ ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool i connect(scriptEngine.data(), &ScriptEngine::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded); connect(scriptEngine.data(), &ScriptEngine::errorLoadingScript, this, &ScriptEngines::onScriptEngineError); + // Shutdown interface when script finishes, if requested + if (exitWhenFinished) { + connect(scriptEngine.data(), &ScriptEngine::finished, this, &ScriptEngines::exitWhenFinished); + } + // get the script engine object to load the script at the designated script URL scriptEngine->loadURL(scriptUrl, reload); } @@ -536,6 +541,10 @@ void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { emit scriptCountChanged(); } +void ScriptEngines::exitWhenFinished() { + qApp->quit(); +} + int ScriptEngines::runScriptInitializers(ScriptEnginePointer scriptEngine) { int ii=0; for (auto initializer : _scriptInitializers) { diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index 376bae4827..6f88e8978d 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -91,7 +91,7 @@ public: * @returns {boolean} */ Q_INVOKABLE ScriptEnginePointer loadScript(const QUrl& scriptFilename = QString(), - bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false); + bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false, bool exitWhenFinished = false); /**jsdoc * @function ScriptDiscoveryService.stopScript @@ -266,6 +266,7 @@ protected: ScriptEnginePointer reloadScript(const QString& scriptName, bool isUserLoaded = true) { return loadScript(scriptName, isUserLoaded, false, false, true); } void removeScriptEngine(ScriptEnginePointer); void onScriptEngineLoaded(const QString& scriptFilename); + void exitWhenFinished(); void onScriptEngineError(const QString& scriptFilename); void launchScriptEngine(ScriptEnginePointer); From 3b566332c6d6fe3413b0bf6b3293dd75b46a8e01 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 14:34:12 -0700 Subject: [PATCH 042/152] Shutdown interface when test script finishes. --- libraries/script-engine/src/ScriptEngines.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index ef4eddbf39..d2834e8c4a 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -456,7 +456,7 @@ void ScriptEngines::reloadAllScripts() { } ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor, - bool activateMainWindow, bool reload, bool exitWhenFinished) { + bool activateMainWindow, bool reload, bool exitWhenFinished) { if (thread() != QThread::currentThread()) { ScriptEnginePointer result { nullptr }; BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(ScriptEnginePointer, result), @@ -496,7 +496,7 @@ ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool i connect(scriptEngine.data(), &ScriptEngine::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded); connect(scriptEngine.data(), &ScriptEngine::errorLoadingScript, this, &ScriptEngines::onScriptEngineError); - // Shutdown interface when script finishes, if requested + // Shutdown Interface when script finishes, if requested if (exitWhenFinished) { connect(scriptEngine.data(), &ScriptEngine::finished, this, &ScriptEngines::exitWhenFinished); } From beb19c53faa18ff57bb0f12b147b2ca5292354e6 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 15:00:14 -0700 Subject: [PATCH 043/152] Added date and time to auto-generated scripts. --- tools/auto-tester/src/Test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index 18d1350402..e9dcad6c72 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -366,10 +366,10 @@ void Test::createRecursiveScript(const QString& topLevelDirectory, bool interact } QTextStream textStream(&allTestsFilename); - textStream << "// This is an automatically generated file, created by auto-tester" << endl << endl; + textStream << "// This is an automatically generated file, created by auto-tester on " << __DATE__ << ", " << __TIME__ << endl << endl; textStream << "var autoTester = Script.require(\"https://github.com/" + githubUser + "/hifi_tests/blob/" - + gitHubBranch + "/tests/utils/autoTester.js?raw=true\");" << endl; + + gitHubBranch + "/tests/utils/autoTester.js?raw=true\");" << endl << endl; textStream << "autoTester.enableRecursive();" << endl; textStream << "autoTester.enableAuto();" << endl << endl; From fe9c6052f73a55aa1873485fa6ae6a7c1d6bf580 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 15:02:11 -0700 Subject: [PATCH 044/152] Added `quitWhenFinished` parameter to the command line. --- interface/src/Application.cpp | 15 +++++++++++---- interface/src/Application.h | 1 + interface/src/ui/Snapshot.cpp | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d8c162a79c..fed6caab89 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -743,7 +743,9 @@ extern DisplayPluginList getDisplayPlugins(); extern InputPluginList getInputPlugins(); extern void saveInputPluginSettings(const InputPluginList& plugins); +// Parameters used for running tests from teh command line const QString TEST_SCRIPT { "--testScript" }; +const QString TEST_QUIT_WHEN_FINISHED { "--quitWhenFinished" }; const QString TEST_SNAPSHOT_LOCATION { "--testSnapshotLocation" }; bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { @@ -1018,11 +1020,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo const QStringList args = arguments(); for (int i = 0; i < args.size() - 1; ++i) { - if (args.at(i) == TEST_SCRIPT) { + if (args.at(i) == TEST_SCRIPT && (i + 1) < args.size()) { QString testScriptPath = args.at(i + 1); if (QFileInfo(testScriptPath).exists()) { setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); - } + } + + // quite when finished parameter must directly follow the test script + if ((i + 2) < args.size() && args.at(i + 2) == TEST_QUIT_WHEN_FINISHED) { + quitWhenFinished = true; + } } else if (args.at(i) == TEST_SNAPSHOT_LOCATION) { // Set test snapshot location only if it is a writeable directory QString pathname(args.at(i + 1)); @@ -2161,8 +2168,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto scriptEngines = DependencyManager::get(); const auto testScript = property(hifi::properties::TEST).toUrl(); - // Set last parameter to exit interface when the test script finishes - scriptEngines->loadScript(testScript, false, false, false, false, true); + // Set last parameter to exit interface when the test script finishes, if so requested + scriptEngines->loadScript(testScript, false, false, false, false, quitWhenFinished); // This is done so we don't get a "connection time-out" message when we haven't passed in a URL. if (arguments().contains("--url")) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 088b74aa9b..cc366c74fe 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -740,5 +740,6 @@ private: std::atomic _pendingRenderEvent { true }; QString testSnapshotLocation; + bool quitWhenFinished { false }; }; #endif // hifi_Application_h diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index d52f01223c..5616b35ac0 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -73,6 +73,7 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { return data; } +#pragma optimize("", off) QString Snapshot::saveSnapshot(QImage image, const QString& filename, const QString& pathname) { QFile* snapshotFile = savedFileForSnapshot(image, false, filename, pathname); @@ -92,6 +93,7 @@ QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { return static_cast(savedFileForSnapshot(image, true, QString(), QString())); } +#pragma optimize("", off) QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename, const QString& userSelectedPathname) { // adding URL to snapshot From 2c6c0a25fcc95b0ba37a356ae460d3da8b796036 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 15:15:30 -0700 Subject: [PATCH 045/152] Add testSnapshotLocation parameter to `takeSnapshot`. --- 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 fed6caab89..54f1ba2606 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7412,7 +7412,7 @@ void Application::loadAvatarBrowser() const { void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) { postLambdaEvent([notify, includeAnimated, aspectRatio, filename, this] { // Get a screenshot and save it - QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename); + QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, testSnapshotLocation); // If we're not doing an animated snapshot as well... if (!includeAnimated) { // Tell the dependency manager that the capture of the still snapshot has taken place. From 887b8285cdc03dce6c9ab369e6f8200ed16668bf Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 16:44:04 -0700 Subject: [PATCH 046/152] Removed unneeded pragma. --- interface/src/ui/Snapshot.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 5616b35ac0..a84e19154b 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -73,7 +73,6 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { return data; } -#pragma optimize("", off) QString Snapshot::saveSnapshot(QImage image, const QString& filename, const QString& pathname) { QFile* snapshotFile = savedFileForSnapshot(image, false, filename, pathname); From da621d99d35c55fae647d2f4510b985f21b218d1 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 16:52:03 -0700 Subject: [PATCH 047/152] Removed unneeded pragma. --- interface/src/ui/Snapshot.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index a84e19154b..d52f01223c 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -92,7 +92,6 @@ QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { return static_cast(savedFileForSnapshot(image, true, QString(), QString())); } -#pragma optimize("", off) QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename, const QString& userSelectedPathname) { // adding URL to snapshot From 1f691edf0d7a731a692757844748c62a9e62a088 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 3 May 2018 17:04:17 -0700 Subject: [PATCH 048/152] Removed platform code (was used for MD files). --- tools/auto-tester/src/Test.cpp | 72 ---------------------------------- tools/auto-tester/src/Test.h | 6 --- 2 files changed, 78 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index e9dcad6c72..e00bc920e5 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -530,26 +530,6 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { QStringList tokens = line.split('"'); relevantTextFromTest.title = tokens[1]; - } else if (lineAssertPlatform.match(line).hasMatch()) { - QStringList platforms = line.split('"'); - relevantTextFromTest.platform = platforms[1]; - - } else if (lineAssertDisplay.match(line).hasMatch()) { - QStringList displays = line.split('"'); - relevantTextFromTest.display = displays[1]; - - } else if (lineAssertCPU.match(line).hasMatch()) { - QStringList cpus = line.split('"'); - relevantTextFromTest.cpu = cpus[1]; - - } else if (lineAssertGPU.match(line).hasMatch()) { - QStringList gpus = line.split('"'); - relevantTextFromTest.gpu = gpus[1]; - - } else if (lineAssertPhysicalMemoryGB.match(line).hasMatch()) { - QStringList physicalMemoryGB = line.split('"'); - relevantTextFromTest.physicalMemoryGB = physicalMemoryGB[1]; - } else if (lineStepSnapshot.match(line).hasMatch()) { QStringList tokens = line.split('"'); QString nameOfStep = tokens[1]; @@ -653,58 +633,6 @@ void Test::createMDFile(const QString& testDirectory) { stream << "## Preconditions" << "\n"; stream << "- In an empty region of a domain with editing rights." << "\n\n"; - // Platform - QStringList platforms = testScriptLines.platform.split(" ");; - if (platforms.size() > 0) { - stream << "## Platforms\n"; - stream << "Run the test on each of the following platforms\n"; - for (int i = 0; i < platforms.size(); ++i) { - // Note that the platforms parameter may include extra spaces, these appear as empty strings in the list - if (platforms[i] != QString()) { - stream << " - " << platforms[i] << "\n"; - } - } - } - - // Display - QStringList displays = testScriptLines.display.split(" "); - if (displays.size()) { - stream << "## Displays\n"; - stream << "Run the test on each of the following displays\n"; - for (int i = 0; i < displays.size(); ++i) { - // Note that the displays parameter may include extra spaces, these appear as empty strings in the list - if (displays[i] != QString()) { - stream << " - " << displays[i] << "\n"; - } - } - } - - // CPU - QStringList cpus = testScriptLines.cpu.split(" "); - if (cpus.size() > 0) { - stream << "## Processors\n"; - stream << "Run the test on each of the following processors\n"; - for (int i = 0; i < cpus.size(); ++i) { - // Note that the cpus parameter may include extra spaces, these appear as empty strings in the list - if (cpus[i] != QString()) { - stream << " - " << cpus[i] << "\n"; - } - } - } - - // GPU - QStringList gpus = testScriptLines.gpu.split(" "); - if (gpus.size() > 0) { - stream << "## Graphics Cards\n"; - stream << "Run the test on graphics cards from each of the following vendors\n"; - for (int i = 0; i < gpus.size(); ++i) { - // Note that the gpus parameter may include extra spaces, these appear as empty strings in the list - if (gpus[i] != QString()) { - stream << " - " << gpus[i] << "\n"; - } - } - } - stream << "## Steps\n"; stream << "Press space bar to advance step by step\n\n"; diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index 02cab53381..b341c1d00f 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -30,12 +30,6 @@ using StepList = std::vector; class ExtractedText { public: QString title; - QString platform; - QString display; - QString cpu; - QString gpu; - QString physicalMemoryGB; - StepList stepList; }; From dd8eac8cb2d156513c49b5fb551ac492ee9eff23 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 4 May 2018 16:14:42 +1200 Subject: [PATCH 049/152] Remove superfluous keyboardControl.js file and references The raiseAndLowerKeyboard.js script is automatically injected into these pages, instead. --- scripts/system/html/entityList.html | 1 - scripts/system/html/entityProperties.html | 1 - scripts/system/html/gridControls.html | 1 - scripts/system/html/js/keyboardControl.js | 73 ----------------------- 4 files changed, 76 deletions(-) delete mode 100644 scripts/system/html/js/keyboardControl.js diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index d608ab63e5..7906a3c97f 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -14,7 +14,6 @@ - diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 8647dca035..8d63261f4c 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -20,7 +20,6 @@ - diff --git a/scripts/system/html/gridControls.html b/scripts/system/html/gridControls.html index c0bd87988d..cd646fed51 100644 --- a/scripts/system/html/gridControls.html +++ b/scripts/system/html/gridControls.html @@ -16,7 +16,6 @@ - diff --git a/scripts/system/html/js/keyboardControl.js b/scripts/system/html/js/keyboardControl.js deleted file mode 100644 index 7a8a314c62..0000000000 --- a/scripts/system/html/js/keyboardControl.js +++ /dev/null @@ -1,73 +0,0 @@ -// -// keyboardControl.js -// -// Created by David Rowe on 28 Sep 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 -// - -function setUpKeyboardControl() { - - var lowerTimer = null; - var isRaised = false; - var KEYBOARD_HEIGHT = 200; - - function raiseKeyboard() { - window.isKeyboardRaised = true; - window.isNumericKeyboard = this.type === "number"; - - if (lowerTimer !== null) { - clearTimeout(lowerTimer); - lowerTimer = null; - } - - EventBridge.emitWebEvent("_RAISE_KEYBOARD" + (this.type === "number" ? "_NUMERIC" : "")); - - if (!isRaised) { - var delta = this.getBoundingClientRect().bottom + 10 - (document.body.clientHeight - KEYBOARD_HEIGHT); - if (delta > 0) { - setTimeout(function () { - document.body.scrollTop += delta; - }, 500); // Allow time for keyboard to be raised in QML. - } - } - - isRaised = true; - } - - function doLowerKeyboard() { - window.isKeyboardRaised = false; - window.isNumericKeyboard = false; - - EventBridge.emitWebEvent("_LOWER_KEYBOARD"); - lowerTimer = null; - isRaised = false; - } - - function lowerKeyboard() { - // Delay lowering keyboard a little in case immediately raise it again. - if (lowerTimer === null) { - lowerTimer = setTimeout(doLowerKeyboard, 20); - } - } - - function documentBlur() { - // Action any pending Lower keyboard event immediately upon leaving document window so that they don't interfere with - // other Entities Editor tab. - if (lowerTimer !== null) { - clearTimeout(lowerTimer); - doLowerKeyboard(); - } - } - - var inputs = document.querySelectorAll("input[type=text], input[type=password], input[type=number], textarea"); - for (var i = 0, length = inputs.length; i < length; i++) { - inputs[i].addEventListener("focus", raiseKeyboard); - inputs[i].addEventListener("blur", lowerKeyboard); - } - - window.addEventListener("blur", documentBlur); -} - From 03da2f09461b54a2b7fc8b119d8454212f62c8f5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 4 May 2018 20:32:53 +1200 Subject: [PATCH 050/152] Only scroll keyboard if necessary --- interface/resources/html/raiseAndLowerKeyboard.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/interface/resources/html/raiseAndLowerKeyboard.js b/interface/resources/html/raiseAndLowerKeyboard.js index a0aa1eb7fe..b2688e3db8 100644 --- a/interface/resources/html/raiseAndLowerKeyboard.js +++ b/interface/resources/html/raiseAndLowerKeyboard.js @@ -44,15 +44,14 @@ }; function scheduleBringToView(timeout) { - - var timer = setTimeout(function () { - clearTimeout(timer); - + setTimeout(function () { + // If the element is not visible because the keyboard has been raised over the top of it, scroll it into view. var elementRect = document.activeElement.getBoundingClientRect(); - var absoluteElementTop = elementRect.top + window.scrollY; - var middle = absoluteElementTop - (window.innerHeight / 2); - - window.scrollTo(0, middle); + var VISUAL_MARGIN = 3 + var delta = elementRect.y + elementRect.height + VISUAL_MARGIN - window.innerHeight; + if (delta > 0) { + window.scrollBy(0, delta); + } }, timeout); } From a57c72df6e4754e497f38827bfa888f954325212 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 4 May 2018 08:53:49 -0700 Subject: [PATCH 051/152] fix entity highlighting during edit mode --- .../controllers/controllerModules/mouseHighlightEntities.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js index 86c96fcf6b..3180e58e2c 100644 --- a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js +++ b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js @@ -12,10 +12,11 @@ /* jslint bitwise: true */ -/* global Script, print, Entities, Picks, HMD, Controller, MyAvatar*/ +/* global Script, print, Entities, Picks, HMD, Controller, MyAvatar, isInEditMode*/ (function() { + Script.include("/~/system/libraries/utils.js"); var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); function MouseHighlightEntities() { @@ -39,7 +40,7 @@ dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity); this.highlightedEntity = null; } - } else if (!this.grabbedEntity) { + } else if (!this.grabbedEntity && !isInEditMode()) { var pickResult = controllerData.mouseRayPick; if (pickResult.type === Picks.INTERSECTED_ENTITY) { var targetEntityID = pickResult.objectID; From a35517d9851aad3ea1c324840912670a3c54bcd0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 May 2018 07:05:10 +1200 Subject: [PATCH 052/152] Fix JSDoc for Users.requestUsernameFromID --- .../script-engine/src/UsersScriptingInterface.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h index f214c3f11c..e80d38239f 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.h +++ b/libraries/script-engine/src/UsersScriptingInterface.h @@ -106,10 +106,11 @@ public slots: void mute(const QUuid& nodeID); /**jsdoc - * Get the user name and machine fingerprint associated with the given UUID. This will only do anything if you're an admin - * of the domain you're in. - * @function Users.getUsernameFromID - * @param {Uuid} nodeID The node or session ID of the user whose username you want. + * Request the user name and machine fingerprint associated with the given UUID. The user name will be returned in a + * {@link Users.usernameFromIDReply|usernameFromIDReply} signal. This will only do anything if you're an admin of the domain + * you're in. + * @function Users.requestUsernameFromID + * @param {Uuid} nodeID The node or session ID of the user whose user name you want. */ void requestUsernameFromID(const QUuid& nodeID); @@ -170,7 +171,8 @@ signals: void enteredIgnoreRadius(); /**jsdoc - * Notifies scripts of the user name and machine fingerprint associated with a UUID. + * Triggered in response to a {@link Users.requestUsernameFromID|requestUsernameFromID} call. Provides the user name and + * machine fingerprint associated with a UUID. * Username and machineFingerprint will be their default constructor output if the requesting user isn't an admin. * @function Users.usernameFromIDReply * @param {Uuid} nodeID From aef5ea093604bc2685f319a9e835ba915323f6be Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Fri, 4 May 2018 12:30:13 -0700 Subject: [PATCH 053/152] Correct usage of the test script URL. --- interface/src/Application.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 54f1ba2606..fc1602e2e3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1022,7 +1022,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo for (int i = 0; i < args.size() - 1; ++i) { if (args.at(i) == TEST_SCRIPT && (i + 1) < args.size()) { QString testScriptPath = args.at(i + 1); - if (QFileInfo(testScriptPath).exists()) { + + // If the URL scheme is "http(s)" then use as is, else - treat it as a local file + // This is done so as not break previous command line scripts + if (testScriptPath.left(4) == "http") { + setProperty(hifi::properties::TEST, QUrl::fromUserInput(testScriptPath)); + } else if (QFileInfo(testScriptPath).exists()) { setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); } From 2c2b74f4c8a965ee7f0171f9d9685d09b9c75a4e Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Fri, 4 May 2018 14:13:14 -0700 Subject: [PATCH 054/152] Removed unused variable. --- tools/auto-tester/src/ui/AutoTester.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index e0f92664ef..59fe5d9de2 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -94,7 +94,6 @@ void AutoTester::saveImage(int index) { QPixmap pixmap; pixmap.loadFromData(downloaders[index]->downloadedData()); - int sdf = pixmap.width(); QImage image = pixmap.toImage(); image = image.convertToFormat(QImage::Format_ARGB32); From 6414fcaae568b31e43c89b72bbc7405d4eb5e88a Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 4 May 2018 14:20:17 -0700 Subject: [PATCH 055/152] fix-another-highlighting-issue --- .../controllerModules/highlightNearbyEntities.js | 11 ++++++++++- .../controllers/controllerModules/inEditMode.js | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index 32e1b4300d..bc09ebee7a 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -56,6 +56,12 @@ return canGrabEntity; }; + this.clearAll = function() { + this.highlightedEntities.forEach(function(entity) { + dispatcherUtils.unhighlightTargetEntity(entity); + }); + }; + this.hasHyperLink = function(props) { return (props.href !== "" && props.href !== undefined); }; @@ -121,7 +127,6 @@ if (channel === 'Hifi-unhighlight-entity') { try { data = JSON.parse(message); - var hand = data.hand; if (hand === dispatcherUtils.LEFT_HAND) { leftHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID); @@ -131,6 +136,9 @@ } catch (e) { print("Failed to parse message"); } + } else if (channel === 'Hifi-unhighlight-all') { + leftHighlightNearbyEntities.clearAll(); + rightHighlightNearbyEntities.clearAll(); } } }; @@ -145,6 +153,7 @@ dispatcherUtils.disableDispatcherModule("RightHighlightNearbyEntities"); } Messages.subscribe('Hifi-unhighlight-entity'); + Messages.subscribe('Hifi-unhighlight-all'); Messages.messageReceived.connect(handleMessage); Script.scriptEnding.connect(cleanup); }()); diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index f7e86f9042..3ad7902d71 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -78,6 +78,7 @@ Script.include("/~/system/libraries/utils.js"); if (controllerData.triggerValues[this.hand] < TRIGGER_ON_VALUE) { this.triggerClicked = false; } + Messages.sendLocalMessage('Hifi-unhighlight-all', ''); return makeRunningValues(true, [], []); } this.triggerClicked = false; From 176d69444f461cdb16d3d26b9ae0f06e17db0476 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 4 May 2018 14:20:17 -0700 Subject: [PATCH 056/152] fix-another-highlighting-issue --- .../controllerModules/highlightNearbyEntities.js | 11 ++++++++++- .../controllers/controllerModules/inEditMode.js | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index 32e1b4300d..bc09ebee7a 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -56,6 +56,12 @@ return canGrabEntity; }; + this.clearAll = function() { + this.highlightedEntities.forEach(function(entity) { + dispatcherUtils.unhighlightTargetEntity(entity); + }); + }; + this.hasHyperLink = function(props) { return (props.href !== "" && props.href !== undefined); }; @@ -121,7 +127,6 @@ if (channel === 'Hifi-unhighlight-entity') { try { data = JSON.parse(message); - var hand = data.hand; if (hand === dispatcherUtils.LEFT_HAND) { leftHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID); @@ -131,6 +136,9 @@ } catch (e) { print("Failed to parse message"); } + } else if (channel === 'Hifi-unhighlight-all') { + leftHighlightNearbyEntities.clearAll(); + rightHighlightNearbyEntities.clearAll(); } } }; @@ -145,6 +153,7 @@ dispatcherUtils.disableDispatcherModule("RightHighlightNearbyEntities"); } Messages.subscribe('Hifi-unhighlight-entity'); + Messages.subscribe('Hifi-unhighlight-all'); Messages.messageReceived.connect(handleMessage); Script.scriptEnding.connect(cleanup); }()); diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index f7e86f9042..3ad7902d71 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -78,6 +78,7 @@ Script.include("/~/system/libraries/utils.js"); if (controllerData.triggerValues[this.hand] < TRIGGER_ON_VALUE) { this.triggerClicked = false; } + Messages.sendLocalMessage('Hifi-unhighlight-all', ''); return makeRunningValues(true, [], []); } this.triggerClicked = false; From 00d2f9494bbc493a8efad13ea2cbe29a1983339c Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 4 May 2018 15:07:20 -0700 Subject: [PATCH 057/152] Change HMACAuth::calculateHash to just call existing methods --- libraries/networking/src/HMACAuth.cpp | 17 ++++------------- libraries/networking/src/HMACAuth.h | 2 +- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/libraries/networking/src/HMACAuth.cpp b/libraries/networking/src/HMACAuth.cpp index 8e57978b5a..515af9a070 100644 --- a/libraries/networking/src/HMACAuth.cpp +++ b/libraries/networking/src/HMACAuth.cpp @@ -106,21 +106,12 @@ HMACAuth::HMACHash HMACAuth::result() { bool HMACAuth::calculateHash(HMACHash& hashResult, const char* data, int dataLen) { QMutexLocker lock(&_lock); - if (!HMAC_Update(_hmacContext, reinterpret_cast(data), dataLen)) { - qCWarning(networking) << "Error occured calling HMAC_Update"; + if (!addData(data, dataLen)) { + qCWarning(networking) << "Error occured calling HMACAuth::addData()"; assert(false); return false; } - hashResult.resize(EVP_MAX_MD_SIZE); - unsigned int hashLen; - if (HMAC_Final(_hmacContext, &hashResult[0], &hashLen)) { - hashResult.resize((size_t)hashLen); - // Clear state for possible reuse. - HMAC_Init_ex(_hmacContext, nullptr, 0, nullptr, nullptr); - return true; - } - qCWarning(networking) << "Error occured calling HMAC_Final"; - assert(false); - return false; + hashResult = result(); + return true; } diff --git a/libraries/networking/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h index ec06bfbda2..59870bb7b6 100644 --- a/libraries/networking/src/HMACAuth.h +++ b/libraries/networking/src/HMACAuth.h @@ -35,7 +35,7 @@ public: HMACHash result(); private: - QMutex _lock; + QMutex _lock { QMutex::Recursive }; struct hmac_ctx_st* _hmacContext; AuthMethod _authMethod; }; From 4ebed7605c979eed603a1d7738730537708e3359 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 4 May 2018 10:10:48 -0700 Subject: [PATCH 058/152] MS14758: Fix avatar reset when gifting worn avatar --- interface/resources/qml/hifi/commerce/purchases/Purchases.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 08e3e7a552..b54a931c51 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -582,7 +582,7 @@ Rectangle { } lightboxPopup.button2text = "CONFIRM"; lightboxPopup.button2method = function() { - MyAvatar.skeletonModelURL = ''; + MyAvatar.useFullAvatarURL(''); root.activeView = "giftAsset"; lightboxPopup.visible = false; }; From 8480bb962b99bdcf2a5b3e457d9cd36106889b68 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 3 May 2018 13:51:50 -0700 Subject: [PATCH 059/152] Fix for crash deep in QML after useFullAvatarURL Here we avoid calling FSTReader::downloadMapping() from within MyAvatar::useFullAvatarURL(). This prevents the error case where a QEventLoop is entered during QML execution. --- interface/src/avatar/MyAvatar.cpp | 18 +++++++++++------- .../src/model-networking/ModelCache.cpp | 14 +++++++++----- .../src/model-networking/ModelCache.h | 2 ++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 249a765d92..3eef1dac3c 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1473,6 +1473,15 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { std::shared_ptr skeletonConnection = std::make_shared(); *skeletonConnection = QObject::connect(_skeletonModel.get(), &SkeletonModel::skeletonLoaded, [this, skeletonModelChangeCount, skeletonConnection]() { if (skeletonModelChangeCount == _skeletonModelChangeCount) { + + if (_fullAvatarModelName.isEmpty()) { + // Store the FST file name into preferences + const auto& mapping = _skeletonModel->getGeometry()->getMapping(); + if (mapping.value("name").isValid()) { + _fullAvatarModelName = mapping.value("name").toString(); + } + } + initHeadBones(); _skeletonModel->setCauterizeBoneSet(_headBoneSet); _fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl(); @@ -1535,12 +1544,7 @@ void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelN if (_fullAvatarURLFromPreferences != fullAvatarURL) { _fullAvatarURLFromPreferences = fullAvatarURL; - if (modelName.isEmpty()) { - QVariantHash fullAvatarFST = FSTReader::downloadMapping(_fullAvatarURLFromPreferences.toString()); - _fullAvatarModelName = fullAvatarFST["name"].toString(); - } else { - _fullAvatarModelName = modelName; - } + _fullAvatarModelName = modelName; } const QString& urlString = fullAvatarURL.toString(); @@ -1548,8 +1552,8 @@ void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelN setSkeletonModelURL(fullAvatarURL); UserActivityLogger::getInstance().changedModel("skeleton", urlString); } + markIdentityDataChanged(); - } void MyAvatar::setAttachmentData(const QVector& attachmentData) { diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index f17cdbb7e8..939168f1b1 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -63,16 +63,18 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) { PROFILE_ASYNC_BEGIN(resource_parse_geometry, "GeometryMappingResource::downloadFinished", _url.toString(), { { "url", _url.toString() } }); - auto mapping = FSTReader::readMapping(data); + // store parsed contents of FST file + _mapping = FSTReader::readMapping(data); + + QString filename = _mapping.value("filename").toString(); - QString filename = mapping.value("filename").toString(); if (filename.isNull()) { qCDebug(modelnetworking) << "Mapping file" << _url << "has no \"filename\" field"; finishedLoading(false); } else { QUrl url = _url.resolved(filename); - QString texdir = mapping.value(TEXDIR_FIELD).toString(); + QString texdir = _mapping.value(TEXDIR_FIELD).toString(); if (!texdir.isNull()) { if (!texdir.endsWith('/')) { texdir += '/'; @@ -82,7 +84,8 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) { _textureBaseUrl = url.resolved(QUrl(".")); } - auto animGraphVariant = mapping.value("animGraphUrl"); + auto animGraphVariant = _mapping.value("animGraphUrl"); + if (animGraphVariant.isValid()) { QUrl fstUrl(animGraphVariant.toString()); if (fstUrl.isValid()) { @@ -95,7 +98,7 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) { } auto modelCache = DependencyManager::get(); - GeometryExtra extra{ mapping, _textureBaseUrl, false }; + GeometryExtra extra{ _mapping, _textureBaseUrl, false }; // Get the raw GeometryResource _geometryResource = modelCache->getResource(url, QUrl(), &extra).staticCast(); @@ -362,6 +365,7 @@ Geometry::Geometry(const Geometry& geometry) { } _animGraphOverrideUrl = geometry._animGraphOverrideUrl; + _mapping = geometry._mapping; } void Geometry::setTextures(const QVariantMap& textureMap) { diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 9532f39ce0..6978e0077e 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -55,6 +55,7 @@ public: virtual bool areTexturesLoaded() const; const QUrl& getAnimGraphOverrideUrl() const { return _animGraphOverrideUrl; } + const QVariantHash& getMapping() const { return _mapping; } protected: friend class GeometryMappingResource; @@ -68,6 +69,7 @@ protected: NetworkMaterials _materials; QUrl _animGraphOverrideUrl; + QVariantHash _mapping; // parsed contents of FST file. private: mutable bool _areTexturesLoaded { false }; From 72526781d9b1fabaeede002d972c48d76e1f631b Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 19 Apr 2018 16:15:22 -0700 Subject: [PATCH 060/152] Additional work on splash screen --- interface/resources/shaders/splashSkybox.frag | 37 +++ interface/src/Application.cpp | 258 +++++++++++------- interface/src/Application.h | 2 + interface/src/Application_render.cpp | 4 +- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/avatar/MyAvatar.h | 2 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 3 +- .../procedural/src/procedural/Procedural.cpp | 4 +- .../src/ui-plugins/PluginContainer.h | 6 + .../oculus/src/OculusBaseDisplayPlugin.cpp | 11 +- 10 files changed, 221 insertions(+), 108 deletions(-) create mode 100644 interface/resources/shaders/splashSkybox.frag diff --git a/interface/resources/shaders/splashSkybox.frag b/interface/resources/shaders/splashSkybox.frag new file mode 100644 index 0000000000..8088b745bc --- /dev/null +++ b/interface/resources/shaders/splashSkybox.frag @@ -0,0 +1,37 @@ + +float noise3D(vec3 p) +{ + return fract(sin(dot(p ,vec3(12.9898,78.233,126.7235))) * 43758.5453); +} + +float worley3D(vec3 p) +{ + float r = 3.0; + vec3 f = floor(p); + vec3 x = fract(p); + for(int i = -1; i<=1; i++) + { + for(int j = -1; j<=1; j++) + { + for(int k = -1; k<=1; k++) + { + vec3 q = vec3(float(i),float(j),float(k)); + vec3 v = q + vec3(noise3D((q+f)*1.11), noise3D((q+f)*1.14), noise3D((q+f)*1.17)) - x; + float d = dot(v, v); + r = min(r, d); + } + } + } + return sqrt(r); +} + + +vec3 getSkyboxColor() { + vec3 color = abs(normalize(_normal)); +// vec2 uv; +// uv.x = 0.5 + atan(_normal.z, _normal.x); +// uv.y = 0.5 - asin(_normal.y); +// uv *= 20.0; +// color.r = worley3D(vec3(uv, iGlobalTime)); + return color; +} \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 59541a3182..4a59cf3549 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -144,6 +144,7 @@ #include #include #include +#include #include #include @@ -385,7 +386,7 @@ Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTRE static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; static const int INTERVAL_TO_CHECK_HMD_WORN_STATUS = 500; // milliseconds static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; - +static const QString ACTIVE_DISPLAY_PLUGIN_SETTING_NAME = "activeDisplayPlugin"; static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; const std::vector> Application::_acceptedExtensions { @@ -1322,10 +1323,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QCoreApplication::processEvents(); _glWidget->createContext(); - // Create the main thread context, the GPU backend, and the display plugins + // Create the main thread context, the GPU backend initializeGL(); - DependencyManager::get()->setGPUContext(_gpuContext); - qCDebug(interfaceapp, "Initialized Display."); + qCDebug(interfaceapp, "Initialized GL"); + + // Initialize the display plugin architecture + initializeDisplayPlugins(); + qCDebug(interfaceapp, "Initialized Display"); + // Create the rendering engine. This can be slow on some machines due to lots of // GPU pipeline creation. initializeRenderEngine(); @@ -2359,6 +2364,10 @@ void Application::onAboutToQuit() { } } + // The active display plugin needs to be loaded before the menu system is active, + // so its persisted explicitly here + Setting::Handle{ ACTIVE_DISPLAY_PLUGIN_SETTING_NAME }.set(getActiveDisplayPlugin()->getName()); + getActiveDisplayPlugin()->deactivate(); if (_autoSwitchDisplayModeSupportedHMDPlugin && _autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) { @@ -2598,10 +2607,81 @@ void Application::initializeGL() { _glWidget->makeCurrent(); _gpuContext = std::make_shared(); + DependencyManager::get()->setGPUContext(_gpuContext); + // Restore the default main thread context _offscreenContext->makeCurrent(); +} - updateDisplayMode(); +static const QString SPLASH_SKYBOX{ "{\"ProceduralEntity\":{ \"version\":2, \"shaderUrl\":\"qrc:///shaders/splashSkybox.frag\" } }" }; + +void Application::initializeDisplayPlugins() { + auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); + Setting::Handle activeDisplayPluginSetting{ ACTIVE_DISPLAY_PLUGIN_SETTING_NAME, displayPlugins.at(0)->getName() }; + auto lastActiveDisplayPluginName = activeDisplayPluginSetting.get(); + + auto defaultDisplayPlugin = displayPlugins.at(0); + // Once time initialization code + DisplayPluginPointer targetDisplayPlugin; + foreach(auto displayPlugin, displayPlugins) { + displayPlugin->setContext(_gpuContext); + if (displayPlugin->getName() == lastActiveDisplayPluginName) { + targetDisplayPlugin = displayPlugin; + } + QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, + [this](const QSize& size) { resizeGL(); }); + QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset); + } + + // The default display plugin needs to be activated first, otherwise the display plugin thread + // may be launched by an external plugin, which is bad + setDisplayPlugin(defaultDisplayPlugin); + + // Now set the desired plugin if it's not the same as the default plugin + if (targetDisplayPlugin != defaultDisplayPlugin) { + setDisplayPlugin(targetDisplayPlugin); + } + + // Submit a default frame to render until the engine starts up + updateRenderArgs(0.0f); + + _offscreenContext->makeCurrent(); + { + QMutexLocker viewLocker(&_renderArgsMutex); + + if (_appRenderArgs._isStereo) { + _gpuContext->enableStereo(true); + _gpuContext->setStereoProjections(_appRenderArgs._eyeProjections); + _gpuContext->setStereoViews(_appRenderArgs._eyeOffsets); + } + + // Frame resources + auto framebufferCache = DependencyManager::get(); + gpu::FramebufferPointer finalFramebuffer = framebufferCache->getFramebuffer(); + std::shared_ptr procedural = std::make_shared(); + procedural->parse(SPLASH_SKYBOX); + + _gpuContext->beginFrame(_appRenderArgs._view, _appRenderArgs._headPose); + gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) { + batch.resetStages(); + batch.enableStereo(false); + batch.setFramebuffer(finalFramebuffer); + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0, 1, 1, 1 }); + + batch.enableSkybox(true); + batch.enableStereo(_appRenderArgs._isStereo); + batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); + procedural->render(batch, _appRenderArgs._renderArgs.getViewFrustum()); + }); + auto frame = _gpuContext->endFrame(); + frame->frameIndex = 0; + frame->framebuffer = finalFramebuffer; + frame->pose = _appRenderArgs._headPose; + frame->framebufferRecycler = [framebufferCache, procedural](const gpu::FramebufferPointer& framebuffer) { + framebufferCache->releaseFramebuffer(framebuffer); + }; + _displayPlugin->submitFrame(frame); + } } void Application::initializeRenderEngine() { @@ -2625,6 +2705,7 @@ void Application::initializeRenderEngine() { } extern void setupPreferences(); +static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bool active); void Application::initializeUi() { // Build a shared canvas / context for the Chromium processes @@ -2766,10 +2847,25 @@ void Application::initializeUi() { offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1); offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); - // Now that the menu is instantiated, ensure the display plugin menu is properly updated - updateDisplayMode(); flushMenuUpdates(); + // Now that the menu is instantiated, ensure the display plugin menu is properly updated + { + auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); + // first sort the plugins into groupings: standard, advanced, developer + std::stable_sort(displayPlugins.begin(), displayPlugins.end(), + [](const DisplayPluginPointer& a, const DisplayPluginPointer& b)->bool { return a->getGrouping() < b->getGrouping(); }); + + // concatenate the groupings into a single list in the order: standard, advanced, developer + for(const auto& displayPlugin : displayPlugins) { + addDisplayPluginToMenu(displayPlugin, _displayPlugin == displayPlugin); + } + + // after all plugins have been added to the menu, add a separator to the menu + auto parent = getPrimaryMenu()->getMenu(MenuOption::OutputMenu); + parent->addSeparator(); + } + // The display plugins are created before the menu now, so we need to do this here to hide the menu bar // now that it exists if (_window && _window->isFullScreen()) { @@ -5723,6 +5819,32 @@ void Application::update(float deltaTime) { } + updateRenderArgs(deltaTime); + + // HACK + // load the view frustum + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. + // Then we can move this logic into the Avatar::simulate call. + myAvatar->preDisplaySide(&_appRenderArgs._renderArgs); + + + { + PerformanceTimer perfTimer("limitless"); + AnimDebugDraw::getInstance().update(); + } + + { + PerformanceTimer perfTimer("limitless"); + DependencyManager::get()->update(); + } + + { // Game loop is done, mark the end of the frame for the scene transactions and the render loop to take over + PerformanceTimer perfTimer("enqueueFrame"); + getMain3DScene()->enqueueFrame(); + } +} + +void Application::updateRenderArgs(float deltaTime) { editRenderArgs([this, deltaTime](AppRenderArgs& appRenderArgs) { PerformanceTimer perfTimer("editRenderArgs"); appRenderArgs._headPose = getHMDSensorPose(); @@ -5746,9 +5868,9 @@ void Application::update(float deltaTime) { QMutexLocker viewLocker(&_viewMutex); // adjust near clip plane to account for sensor scaling. auto adjustedProjection = glm::perspective(glm::radians(_fieldOfView.get()), - getActiveDisplayPlugin()->getRecommendedAspectRatio(), - DEFAULT_NEAR_CLIP * sensorToWorldScale, - DEFAULT_FAR_CLIP); + getActiveDisplayPlugin()->getRecommendedAspectRatio(), + DEFAULT_NEAR_CLIP * sensorToWorldScale, + DEFAULT_FAR_CLIP); _viewFrustum.setProjection(adjustedProjection); _viewFrustum.calculate(); } @@ -5764,8 +5886,14 @@ void Application::update(float deltaTime) { } { PROFILE_RANGE(render, "/resizeGL"); - PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + bool showWarnings = false; + bool suppressShortTimings = false; + auto menu = Menu::getInstance(); + if (menu) { + suppressShortTimings = menu->isOptionChecked(MenuOption::SuppressShortTimings); + showWarnings = menu->isOptionChecked(MenuOption::PipelineWarnings); + } + PerformanceWarning::setSuppressShortTimings(suppressShortTimings); PerformanceWarning warn(showWarnings, "Application::paintGL()"); resizeGL(); } @@ -5821,12 +5949,6 @@ void Application::update(float deltaTime) { } } - // HACK - // load the view frustum - // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. - // Then we can move this logic into the Avatar::simulate call. - myAvatar->preDisplaySide(&appRenderArgs._renderArgs); - { QMutexLocker viewLocker(&_viewMutex); _myCamera.loadViewFrustum(_displayViewFrustum); @@ -5838,21 +5960,6 @@ void Application::update(float deltaTime) { appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum); } }); - - { - PerformanceTimer perfTimer("limitless"); - AnimDebugDraw::getInstance().update(); - } - - { - PerformanceTimer perfTimer("limitless"); - DependencyManager::get()->update(); - } - - { // Game loop is done, mark the end of the frame for the scene transactions and the render loop to take over - PerformanceTimer perfTimer("enqueueFrame"); - getMain3DScene()->enqueueFrame(); - } } void Application::queryAvatars() { @@ -7493,15 +7600,19 @@ void Application::shareSnapshot(const QString& path, const QUrl& href) { } float Application::getRenderResolutionScale() const { - if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionOne)) { + auto menu = Menu::getInstance(); + if (!menu) { return 1.0f; - } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionTwoThird)) { + } + if (menu->isOptionChecked(MenuOption::RenderResolutionOne)) { + return 1.0f; + } else if (menu->isOptionChecked(MenuOption::RenderResolutionTwoThird)) { return 0.666f; - } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionHalf)) { + } else if (menu->isOptionChecked(MenuOption::RenderResolutionHalf)) { return 0.5f; - } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionThird)) { + } else if (menu->isOptionChecked(MenuOption::RenderResolutionThird)) { return 0.333f; - } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionQuarter)) { + } else if (menu->isOptionChecked(MenuOption::RenderResolutionQuarter)) { return 0.25f; } else { return 1.0f; @@ -7725,7 +7836,7 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const { static const char* EXCLUSION_GROUP_KEY = "exclusionGroup"; -static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { +static void addDisplayPluginToMenu(const DisplayPluginPointer& displayPlugin, bool active) { auto menu = Menu::getInstance(); QString name = displayPlugin->getName(); auto grouping = displayPlugin->getGrouping(); @@ -7770,65 +7881,12 @@ void Application::updateDisplayMode() { qFatal("Attempted to switch display plugins from a non-main thread"); } - auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins(); - - // Once time initialization code - static std::once_flag once; - std::call_once(once, [&] { - foreach(auto displayPlugin, displayPlugins) { - displayPlugin->setContext(_gpuContext); - QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, - [this](const QSize& size) { resizeGL(); }); - QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset); - } - }); - // Once time initialization code that depends on the UI being available - auto menu = Menu::getInstance(); - if (menu) { - static std::once_flag onceUi; - std::call_once(onceUi, [&] { - bool first = true; - - // first sort the plugins into groupings: standard, advanced, developer - DisplayPluginList standard; - DisplayPluginList advanced; - DisplayPluginList developer; - foreach(auto displayPlugin, displayPlugins) { - displayPlugin->setContext(_gpuContext); - auto grouping = displayPlugin->getGrouping(); - switch (grouping) { - case Plugin::ADVANCED: - advanced.push_back(displayPlugin); - break; - case Plugin::DEVELOPER: - developer.push_back(displayPlugin); - break; - default: - standard.push_back(displayPlugin); - break; - } - } - - // concatenate the groupings into a single list in the order: standard, advanced, developer - standard.insert(std::end(standard), std::begin(advanced), std::end(advanced)); - standard.insert(std::end(standard), std::begin(developer), std::end(developer)); - - foreach(auto displayPlugin, standard) { - addDisplayPluginToMenu(displayPlugin, first); - first = false; - } - - // after all plugins have been added to the menu, add a separator to the menu - auto parent = menu->getMenu(MenuOption::OutputMenu); - parent->addSeparator(); - }); - - } - + auto displayPlugins = getDisplayPlugins(); // Default to the first item on the list, in case none of the menu items match DisplayPluginPointer newDisplayPlugin = displayPlugins.at(0); + auto menu = getPrimaryMenu(); if (menu) { foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { QString name = displayPlugin->getName(); @@ -7852,6 +7910,14 @@ void Application::updateDisplayMode() { } void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) { + if (newDisplayPlugin == _displayPlugin) { + return; + } + + // FIXME don't have the application directly set the state of the UI, + // instead emit a signal that the display plugin is changing and let + // the desktop lock itself. Reduces coupling between the UI and display + // plugins auto offscreenUi = DependencyManager::get(); auto desktop = offscreenUi->getDesktop(); auto menu = Menu::getInstance(); @@ -7862,8 +7928,8 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) { bool wasRepositionLocked = false; if (desktop) { // Tell the desktop to no reposition (which requires plugin info), until we have set the new plugin, below. - wasRepositionLocked = offscreenUi->getDesktop()->property("repositionLocked").toBool(); - offscreenUi->getDesktop()->setProperty("repositionLocked", true); + wasRepositionLocked = desktop->property("repositionLocked").toBool(); + desktop->setProperty("repositionLocked", true); } if (_displayPlugin) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 654b5c797b..b801ec6d34 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -148,6 +148,7 @@ public: Q_INVOKABLE QString getUserAgent(); void initializeGL(); + void initializeDisplayPlugins(); void initializeRenderEngine(); void initializeUi(); @@ -671,6 +672,7 @@ private: using RenderArgsEditor = std::function ; void editRenderArgs(RenderArgsEditor editor); + void updateRenderArgs(float deltaTime); Overlays _overlays; diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index e1015ca5d1..76babe3682 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -13,8 +13,9 @@ #include #include -#include "ui/Stats.h" +#include #include +#include "ui/Stats.h" #include "Util.h" @@ -233,3 +234,4 @@ void Application::runRenderFrame(RenderArgs* renderArgs) { _renderEngine->run(); } } + diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 15b220c63b..6c6f6d4d41 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2039,7 +2039,7 @@ void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) { } } -void MyAvatar::preDisplaySide(RenderArgs* renderArgs) { +void MyAvatar::preDisplaySide(const RenderArgs* renderArgs) { // toggle using the cauterizedBones depending on where the camera is and the rendering pass type. const bool shouldDrawHead = shouldRenderHead(renderArgs); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index ac3d3cd2f4..154e2e4d09 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -272,7 +272,7 @@ public: void update(float deltaTime); virtual void postUpdate(float deltaTime, const render::ScenePointer& scene) override; - void preDisplaySide(RenderArgs* renderArgs); + void preDisplaySide(const RenderArgs* renderArgs); const glm::mat4& getHMDSensorMatrix() const { return _hmdSensorMatrix; } const glm::vec3& getHMDSensorPosition() const { return _hmdSensorPosition; } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 4b33565bfd..3cfc0651d8 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -336,9 +336,8 @@ void OpenGLDisplayPlugin::deactivate() { _container->showDisplayPluginsTools(false); if (!_container->currentDisplayActions().isEmpty()) { - auto menu = _container->getPrimaryMenu(); foreach(auto itemInfo, _container->currentDisplayActions()) { - menu->removeMenuItem(itemInfo.first, itemInfo.second); + _container->removeMenuItem(itemInfo.first, itemInfo.second); } _container->currentDisplayActions().clear(); } diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index c155d5bd7f..19c4a62443 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -19,7 +19,7 @@ #include #include #include - +#include #include "ProceduralCommon_frag.h" #include "Logging.h" @@ -178,6 +178,8 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) { return; } _shaderPath = shaderUrl.toLocalFile(); + } else if (shaderUrl.scheme() == URL_SCHEME_QRC) { + _shaderPath = ":" + shaderUrl.path(); } else { _networkShader = ShaderCache::instance().getShader(shaderUrl); } diff --git a/libraries/ui-plugins/src/ui-plugins/PluginContainer.h b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h index da9ea46cf4..5df20ff30c 100644 --- a/libraries/ui-plugins/src/ui-plugins/PluginContainer.h +++ b/libraries/ui-plugins/src/ui-plugins/PluginContainer.h @@ -54,6 +54,12 @@ public: void setFullscreen(const QScreen* targetScreen, bool hideMenu = false); void unsetFullscreen(const QScreen* avoidScreen = nullptr); + // FIXME remove access tot he menu from the plugin container + // Instead let display plugins expose a structure about the kinds + // of actions and menu items they want to have appear when they are + // active and allow the application to act on that when the display + // plugin becomes active (or when the UI is initialized, and a + // display plugin is already active) virtual ui::Menu* getPrimaryMenu() = 0; virtual void showDisplayPluginsTools(bool show = true) = 0; virtual void requestReset() = 0; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index d8f2db75c9..7e337070d3 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -166,12 +166,11 @@ void OculusBaseDisplayPlugin::deactivateSession() { //_session = nullptr; } void OculusBaseDisplayPlugin::updatePresentPose() { - //mat4 sensorResetMat; - //_currentPresentFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds(); - //_currentPresentFrameInfo.predictedDisplayTime = ovr_GetPredictedDisplayTime(_session, _currentFrame->frameIndex); - //auto trackingState = ovr_GetTrackingState(_session, _currentRenderFrameInfo.predictedDisplayTime, ovrFalse); - //_currentPresentFrameInfo.presentPose = toGlm(trackingState.HeadPose.ThePose); - _currentPresentFrameInfo.presentPose = _currentPresentFrameInfo.renderPose; + _currentPresentFrameInfo.sensorSampleTime = ovr_GetTimeInSeconds(); + _currentPresentFrameInfo.predictedDisplayTime = ovr_GetPredictedDisplayTime(_session, 0); + auto trackingState = ovr_GetTrackingState(_session, _currentRenderFrameInfo.predictedDisplayTime, ovrFalse); + _currentPresentFrameInfo.presentPose = toGlm(trackingState.HeadPose.ThePose); + _currentPresentFrameInfo.renderPose = _currentPresentFrameInfo.presentPose; } OculusBaseDisplayPlugin::~OculusBaseDisplayPlugin() { From 803bd284a644366e315138fa3c80a98e51ec17ae Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 1 May 2018 14:41:23 -0700 Subject: [PATCH 061/152] Alternate shader --- interface/resources/shaders/splashSkybox.frag | 70 +++++++++++-------- interface/src/Application.cpp | 5 +- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/interface/resources/shaders/splashSkybox.frag b/interface/resources/shaders/splashSkybox.frag index 8088b745bc..38c89b4d26 100644 --- a/interface/resources/shaders/splashSkybox.frag +++ b/interface/resources/shaders/splashSkybox.frag @@ -1,37 +1,47 @@ +const vec3 COLOR = vec3(0x00, 0xD8, 0x02) / vec3(0xFF); +const float CUTOFF = 0.65; +const float NOISE_MULT = 8.0; +const float NOISE_POWER = 1.0; -float noise3D(vec3 p) -{ - return fract(sin(dot(p ,vec3(12.9898,78.233,126.7235))) * 43758.5453); +float noise4D(vec4 p) { + return fract(sin(dot(p ,vec4(12.9898,78.233,126.7235, 593.2241))) * 43758.5453); } -float worley3D(vec3 p) -{ - float r = 3.0; - vec3 f = floor(p); - vec3 x = fract(p); - for(int i = -1; i<=1; i++) - { - for(int j = -1; j<=1; j++) - { - for(int k = -1; k<=1; k++) - { - vec3 q = vec3(float(i),float(j),float(k)); - vec3 v = q + vec3(noise3D((q+f)*1.11), noise3D((q+f)*1.14), noise3D((q+f)*1.17)) - x; - float d = dot(v, v); - r = min(r, d); - } - } - } +float worley4D(vec4 p) { + float r = 3.0; + vec4 f = floor(p); + vec4 x = fract(p); + for(int i = -1; i<=1; i++) + { + for(int j = -1; j<=1; j++) + { + for(int k = -1; k<=1; k++) + { + for (int l = -1; l <= 1; l++) { + vec4 q = vec4(float(i),float(j),float(k), float(l)); + vec4 v = q + vec4(noise4D((q+f)*1.11), noise4D((q+f)*1.14), noise4D((q+f)*1.17), noise4D((q+f)*1.20)) - x; + float d = dot(v, v); + r = min(r, d); + } + } + } + } return sqrt(r); -} +} +vec3 mainColor(vec3 direction) { + float n = worley4D(vec4(direction * NOISE_MULT, iGlobalTime / 3.0)); + n = 1.0 - n; + n = pow(n, NOISE_POWER); + if (n < CUTOFF) { + return vec3(0.0); + } + + n = (n - CUTOFF) / (1.0 - CUTOFF); + return COLOR * (1.0 - n); +} + vec3 getSkyboxColor() { - vec3 color = abs(normalize(_normal)); -// vec2 uv; -// uv.x = 0.5 + atan(_normal.z, _normal.x); -// uv.y = 0.5 - asin(_normal.y); -// uv *= 20.0; -// color.r = worley3D(vec3(uv, iGlobalTime)); - return color; -} \ No newline at end of file + return mainColor(normalize(_normal)); +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4a59cf3549..e6830a04c8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2671,6 +2671,9 @@ void Application::initializeDisplayPlugins() { batch.enableSkybox(true); batch.enableStereo(_appRenderArgs._isStereo); batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); + batch.runLambda([] { + // update uniform values + }); procedural->render(batch, _appRenderArgs._renderArgs.getViewFrustum()); }); auto frame = _gpuContext->endFrame(); @@ -3016,7 +3019,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _thirdPersonHMDCameraBoomValid = false; _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + if (isOptionChecked(MenuOption::CenterPlayerInView)) { _myCamera.setPosition(myAvatar->getDefaultEyePosition() + _myCamera.getOrientation() * boomOffset); } From 38f43bdc6802e695cb78470eb65a75c62fd027de Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Tue, 1 May 2018 16:49:00 -0700 Subject: [PATCH 062/152] Disable current splash frame implementaton --- interface/src/Application.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e6830a04c8..ea487c2239 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2646,6 +2646,9 @@ void Application::initializeDisplayPlugins() { updateRenderArgs(0.0f); _offscreenContext->makeCurrent(); + +#define ENABLE_SPLASH_FRAME 0 +#if ENABLE_SPLASH_FRAME { QMutexLocker viewLocker(&_renderArgsMutex); @@ -2666,14 +2669,10 @@ void Application::initializeDisplayPlugins() { batch.resetStages(); batch.enableStereo(false); batch.setFramebuffer(finalFramebuffer); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0, 1, 1, 1 }); - + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, { 0, 0, 0, 1 }); batch.enableSkybox(true); batch.enableStereo(_appRenderArgs._isStereo); batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); - batch.runLambda([] { - // update uniform values - }); procedural->render(batch, _appRenderArgs._renderArgs.getViewFrustum()); }); auto frame = _gpuContext->endFrame(); @@ -2685,6 +2684,7 @@ void Application::initializeDisplayPlugins() { }; _displayPlugin->submitFrame(frame); } +#endif } void Application::initializeRenderEngine() { From 1be948ee2846b02e98e974568798ff275cf40cf3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 May 2018 12:03:18 +1200 Subject: [PATCH 063/152] Scroll element into view if it's been moved off the screen --- interface/resources/html/raiseAndLowerKeyboard.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/resources/html/raiseAndLowerKeyboard.js b/interface/resources/html/raiseAndLowerKeyboard.js index b2688e3db8..15df94334c 100644 --- a/interface/resources/html/raiseAndLowerKeyboard.js +++ b/interface/resources/html/raiseAndLowerKeyboard.js @@ -45,12 +45,15 @@ function scheduleBringToView(timeout) { setTimeout(function () { - // If the element is not visible because the keyboard has been raised over the top of it, scroll it into view. + // If the element is not visible because the keyboard has been raised over the top of it, scroll it up into view. + // If the element is not visible because the keyboard raising has moved it off screen, scroll it down into view. var elementRect = document.activeElement.getBoundingClientRect(); var VISUAL_MARGIN = 3 var delta = elementRect.y + elementRect.height + VISUAL_MARGIN - window.innerHeight; if (delta > 0) { window.scrollBy(0, delta); + } else if (elementRect.y < VISUAL_MARGIN) { + window.scrollBy(0, elementRect.y - VISUAL_MARGIN); } }, timeout); } From 3c2bee757a521e918d195772a88dc8e3913f50a4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 May 2018 12:14:40 +1200 Subject: [PATCH 064/152] Remove calls to function that's been removed --- scripts/system/html/js/entityList.js | 2 -- scripts/system/html/js/entityProperties.js | 4 +--- scripts/system/html/js/gridControls.js | 2 -- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 625aa26b00..88b3ccbf7c 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -444,8 +444,6 @@ function loaded() { augmentSpinButtons(); - setUpKeyboardControl(); - // Disable right-click context menu which is not visible in the HMD and makes it seem like the app has locked document.addEventListener("contextmenu", function (event) { event.preventDefault(); diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 4b6329db44..2194b539ef 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -7,7 +7,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html /* global alert, augmentSpinButtons, clearTimeout, console, document, Element, EventBridge, - HifiEntityUI, JSONEditor, openEventBridge, setUpKeyboardControl, setTimeout, window, _ $ */ + HifiEntityUI, JSONEditor, openEventBridge, setTimeout, window, _ $ */ var PI = 3.14159265358979; var DEGREES_TO_RADIANS = PI / 180.0; @@ -2157,8 +2157,6 @@ function loaded() { augmentSpinButtons(); - setUpKeyboardControl(); - // Disable right-click context menu which is not visible in the HMD and makes it seem like the app has locked document.addEventListener("contextmenu", function(event) { event.preventDefault(); diff --git a/scripts/system/html/js/gridControls.js b/scripts/system/html/js/gridControls.js index be4271788e..79a169400a 100644 --- a/scripts/system/html/js/gridControls.js +++ b/scripts/system/html/js/gridControls.js @@ -129,8 +129,6 @@ function loaded() { augmentSpinButtons(); - setUpKeyboardControl(); - EventBridge.emitWebEvent(JSON.stringify({ type: 'init' })); }); document.addEventListener("keydown", function (keyDown) { From 5e6b83a6346bde1d00fc148c073d0b7687a01692 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 May 2018 12:14:51 +1200 Subject: [PATCH 065/152] Lint --- .../resources/html/raiseAndLowerKeyboard.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/interface/resources/html/raiseAndLowerKeyboard.js b/interface/resources/html/raiseAndLowerKeyboard.js index 15df94334c..f40c0d7376 100644 --- a/interface/resources/html/raiseAndLowerKeyboard.js +++ b/interface/resources/html/raiseAndLowerKeyboard.js @@ -7,6 +7,9 @@ // // Sends messages over the EventBridge when text input is required. // + +/* global document, window, console, setTimeout, setInterval, EventBridge */ + (function () { var POLL_FREQUENCY = 500; // ms var MAX_WARNINGS = 3; @@ -37,18 +40,18 @@ } return false; } - }; + } function shouldSetNumeric() { return document.activeElement.type === "number"; - }; + } function scheduleBringToView(timeout) { setTimeout(function () { // If the element is not visible because the keyboard has been raised over the top of it, scroll it up into view. // If the element is not visible because the keyboard raising has moved it off screen, scroll it down into view. var elementRect = document.activeElement.getBoundingClientRect(); - var VISUAL_MARGIN = 3 + var VISUAL_MARGIN = 3; var delta = elementRect.y + elementRect.height + VISUAL_MARGIN - window.innerHeight; if (delta > 0) { window.scrollBy(0, delta); @@ -64,11 +67,13 @@ var passwordField = shouldSetPasswordField(); if (isWindowFocused && - (keyboardRaised !== window.isKeyboardRaised || numericKeyboard !== window.isNumericKeyboard || passwordField !== window.isPasswordField)) { + (keyboardRaised !== window.isKeyboardRaised || numericKeyboard !== window.isNumericKeyboard + || passwordField !== window.isPasswordField)) { if (typeof EventBridge !== "undefined" && EventBridge !== null) { EventBridge.emitWebEvent( - keyboardRaised ? ("_RAISE_KEYBOARD" + (numericKeyboard ? "_NUMERIC" : "") + (passwordField ? "_PASSWORD" : "")) : "_LOWER_KEYBOARD" + keyboardRaised ? ("_RAISE_KEYBOARD" + (numericKeyboard ? "_NUMERIC" : "") + + (passwordField ? "_PASSWORD" : "")) : "_LOWER_KEYBOARD" ); } else { if (numWarnings < MAX_WARNINGS) { @@ -79,7 +84,7 @@ if (!window.isKeyboardRaised) { scheduleBringToView(250); // Allow time for keyboard to be raised in QML. - // 2DO: should it be rather done from 'client area height changed' event? + // 2DO: should it be rather done from 'client area height changed' event? } window.isKeyboardRaised = keyboardRaised; From 6a55e67ce9cd01ed29825d14889a1d0d2ad902c6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 5 May 2018 16:39:03 -0700 Subject: [PATCH 066/152] avoid misaligned pointer deref --- libraries/gpu/src/gpu/Texture_ktx.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 0822af3cfb..bb081637be 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -46,13 +46,14 @@ struct GPUKTXPayload { memcpy(data, &_samplerDesc, sizeof(Sampler::Desc)); data += sizeof(Sampler::Desc); - + // We can't copy the bitset in Texture::Usage in a crossplateform manner // So serialize it manually - *(uint32*)data = _usage._flags.to_ulong(); + uint32 usageData = _usage._flags.to_ulong(); + memcpy(data, &usageData, sizeof(uint32)); data += sizeof(uint32); - *(TextureUsageType*)data = _usageType; + memcpy(data, &_usageType, sizeof(TextureUsageType)); data += sizeof(TextureUsageType); return data + PADDING; @@ -77,10 +78,12 @@ struct GPUKTXPayload { memcpy(&_samplerDesc, data, sizeof(Sampler::Desc)); data += sizeof(Sampler::Desc); - + // We can't copy the bitset in Texture::Usage in a crossplateform manner // So unserialize it manually - _usage = Texture::Usage(*(const uint32*)data); + uint32 usageData; + memcpy(&usageData, data, sizeof(uint32)); + _usage = Texture::Usage(usageData); data += sizeof(uint32); _usageType = *(const TextureUsageType*)data; @@ -710,4 +713,4 @@ bool Texture::evalTextureFormat(const ktx::Header& header, Element& mipFormat, E return false; } return true; -} \ No newline at end of file +} From 30c5fa6fa167edd515440ff301c3ffc6fd7dbec0 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 5 May 2018 20:45:06 -0700 Subject: [PATCH 067/152] fix divide-by-zero asan warning in LODManager::autoAdjustLOD --- interface/src/LODManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index d06ba14bcf..da1f14c450 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -70,7 +70,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { // Note: we MUST clamp the blend to 1.0 for stability float blend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f; _avgRenderTime = (1.0f - blend) * _avgRenderTime + blend * maxRenderTime; // msec - if (!_automaticLODAdjust) { + if (!_automaticLODAdjust || _avgRenderTime == 0.0f) { // early exit return; } From 677c99abd46e429090a4ebd3d85b2f7145e9ea6e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 5 May 2018 20:50:54 -0700 Subject: [PATCH 068/152] use memcpy on _usageType as well --- libraries/gpu/src/gpu/Texture_ktx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index bb081637be..129c125411 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -86,7 +86,7 @@ struct GPUKTXPayload { _usage = Texture::Usage(usageData); data += sizeof(uint32); - _usageType = *(const TextureUsageType*)data; + memcpy(&_usageType, data, sizeof(TextureUsageType)); return true; } From b4cfea2fbc4793bc9f3fddcf8949ab67cf826c19 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Sun, 6 May 2018 17:17:06 +0300 Subject: [PATCH 069/152] FB14818 Login page for steam is blank --- interface/resources/qml/LoginDialog/SignInBody.qml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/LoginDialog/SignInBody.qml b/interface/resources/qml/LoginDialog/SignInBody.qml index c4b6c2aee1..9cb1add704 100644 --- a/interface/resources/qml/LoginDialog/SignInBody.qml +++ b/interface/resources/qml/LoginDialog/SignInBody.qml @@ -84,11 +84,9 @@ Item { height: undefined // invalidate so that the image's size sets the height focus: true - style: OriginalStyles.ButtonStyle { - background: Image { - id: buttonImage - source: "../../images/steam-sign-in.png" - } + background: Image { + id: buttonImage + source: "../../images/steam-sign-in.png" } onClicked: signInBody.login() } From c2004debd57921c6d2f3658ea05e0b0e2232b94a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 7 May 2018 11:41:19 -0700 Subject: [PATCH 070/152] test using highp floats everywhere for android --- .../gpu-gl/src/gpu/gl41/GL41BackendShader.cpp | 1 - .../gpu-gl/src/gpu/gl45/GL45BackendShader.cpp | 1 - .../src/gpu/gles/GLESBackendShader.cpp | 7 +++---- libraries/graphics/src/graphics/Light.slh | 2 +- .../src/graphics/LightIrradiance.shared.slh | 4 ++-- .../src/graphics/LightVolume.shared.slh | 4 ++-- libraries/graphics/src/graphics/Material.slh | 11 ++++------- .../src/graphics/SphericalHarmonics.shared.slh | 18 +++++++++--------- libraries/render-utils/src/LightingModel.slh | 8 ++++---- 9 files changed, 25 insertions(+), 31 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp index 151b5bd1f9..64c9033cf7 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp @@ -17,7 +17,6 @@ std::string GL41Backend::getBackendShaderHeader() const { static const std::string header( R"SHADER(#version 410 core #define GPU_GL410 - #define PRECISIONQ #define BITFIELD int )SHADER"); return header; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp index 6f6ded518f..44e439df55 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendShader.cpp @@ -18,7 +18,6 @@ std::string GL45Backend::getBackendShaderHeader() const { static const std::string header( R"SHADER(#version 450 core #define GPU_GL450 - #define PRECISIONQ #define BITFIELD int )SHADER" #ifdef GPU_SSBO_TRANSFORM_OBJECT diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp index 4278d732c8..7e8056ba79 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendShader.cpp @@ -17,10 +17,9 @@ std::string GLESBackend::getBackendShaderHeader() const { static const std::string header( R"SHADER(#version 310 es #extension GL_EXT_texture_buffer : enable - precision lowp float; // check precision 2 - precision lowp samplerBuffer; - precision lowp sampler2DShadow; - #define PRECISIONQ highp + precision highp float; + precision highp samplerBuffer; + precision highp sampler2DShadow; #define BITFIELD highp int )SHADER"); return header; diff --git a/libraries/graphics/src/graphics/Light.slh b/libraries/graphics/src/graphics/Light.slh index c8992730f0..53b840f5fb 100644 --- a/libraries/graphics/src/graphics/Light.slh +++ b/libraries/graphics/src/graphics/Light.slh @@ -34,7 +34,7 @@ vec3 getLightIrradiance(Light l) { return lightIrradiance_getIrradiance(l.irradi // Light Ambient struct LightAmbient { - PRECISIONQ vec4 _ambient; + vec4 _ambient; SphericalHarmonics _ambientSphere; mat4 transform; }; diff --git a/libraries/graphics/src/graphics/LightIrradiance.shared.slh b/libraries/graphics/src/graphics/LightIrradiance.shared.slh index 4ae7967bf5..13d6cf4b93 100644 --- a/libraries/graphics/src/graphics/LightIrradiance.shared.slh +++ b/libraries/graphics/src/graphics/LightIrradiance.shared.slh @@ -14,9 +14,9 @@ #define LightIrradianceConstRef LightIrradiance struct LightIrradiance { - PRECISIONQ vec4 colorIntensity; + vec4 colorIntensity; // falloffRadius, cutoffRadius, falloffSpot, spare - PRECISIONQ vec4 attenuation; + vec4 attenuation; }; diff --git a/libraries/graphics/src/graphics/LightVolume.shared.slh b/libraries/graphics/src/graphics/LightVolume.shared.slh index 4e4359eac0..3f0cb135f5 100644 --- a/libraries/graphics/src/graphics/LightVolume.shared.slh +++ b/libraries/graphics/src/graphics/LightVolume.shared.slh @@ -16,8 +16,8 @@ #define LightVolumeConstRef LightVolume struct LightVolume { - PRECISIONQ vec4 positionRadius; - PRECISIONQ vec4 directionSpotCos; + vec4 positionRadius; + vec4 directionSpotCos; }; bool lightVolume_isPoint(LightVolume lv) { return bool(lv.directionSpotCos.w < 0.f); } diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index ecf3c18a0e..dd2985b4da 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -15,10 +15,10 @@ // to what is provided by the uniform buffer, or the material key has the wrong bits struct Material { - PRECISIONQ vec4 _emissiveOpacity; - PRECISIONQ vec4 _albedoRoughness; - PRECISIONQ vec4 _fresnelMetallic; - PRECISIONQ vec4 _scatteringSpare2Key; + vec4 _emissiveOpacity; + vec4 _albedoRoughness; + vec4 _fresnelMetallic; + vec4 _scatteringSpare2Key; }; uniform materialBuffer { @@ -64,7 +64,4 @@ const BITFIELD OCCLUSION_MAP_BIT = 0x00004000; const BITFIELD LIGHTMAP_MAP_BIT = 0x00008000; const BITFIELD SCATTERING_MAP_BIT = 0x00010000; -#ifdef GL_ES -precision lowp float; -#endif <@endif@> diff --git a/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh b/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh index 6e1763dcba..312824c5a3 100644 --- a/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh +++ b/libraries/graphics/src/graphics/SphericalHarmonics.shared.slh @@ -16,15 +16,15 @@ #define SphericalHarmonicsConstRef SphericalHarmonics struct SphericalHarmonics { - PRECISIONQ vec4 L00; - PRECISIONQ vec4 L1m1; - PRECISIONQ vec4 L10; - PRECISIONQ vec4 L11; - PRECISIONQ vec4 L2m2; - PRECISIONQ vec4 L2m1; - PRECISIONQ vec4 L20; - PRECISIONQ vec4 L21; - PRECISIONQ vec4 L22; + vec4 L00; + vec4 L1m1; + vec4 L10; + vec4 L11; + vec4 L2m2; + vec4 L2m1; + vec4 L20; + vec4 L21; + vec4 L22; }; vec4 sphericalHarmonics_evalSphericalLight(SphericalHarmonicsConstRef sh, vec3 direction) { diff --git a/libraries/render-utils/src/LightingModel.slh b/libraries/render-utils/src/LightingModel.slh index 6a5982f1e8..8abdb5cbf9 100644 --- a/libraries/render-utils/src/LightingModel.slh +++ b/libraries/render-utils/src/LightingModel.slh @@ -14,10 +14,10 @@ <@func declareLightingModel()@> struct LightingModel { - PRECISIONQ vec4 _UnlitEmissiveLightmapBackground; - PRECISIONQ vec4 _ScatteringDiffuseSpecularAlbedo; - PRECISIONQ vec4 _AmbientDirectionalPointSpot; - PRECISIONQ vec4 _ShowContourObscuranceWireframe; + vec4 _UnlitEmissiveLightmapBackground; + vec4 _ScatteringDiffuseSpecularAlbedo; + vec4 _AmbientDirectionalPointSpot; + vec4 _ShowContourObscuranceWireframe; }; uniform lightingModelBuffer{ From 646c0ec987eb285e641ef1ca9a75bfc45f888136 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 7 May 2018 11:56:47 -0700 Subject: [PATCH 071/152] MS14878: Prevent wallet passphrase leak in specific case --- scripts/system/marketplaces/marketplaces.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index a05778e2dd..c3edee264f 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -789,10 +789,14 @@ var selectionDisplay = null; // for gridTool.js to ignore var savedDisablePreviewOptionLocked = false; var savedDisablePreviewOption = Menu.isOptionChecked("Disable Preview");; function maybeEnableHMDPreview() { - setTabletVisibleInSecondaryCamera(true); - DesktopPreviewProvider.setPreviewDisabledReason("USER"); - Menu.setIsOptionChecked("Disable Preview", savedDisablePreviewOption); - savedDisablePreviewOptionLocked = false; + // Set a small timeout to prevent sensitive data from being shown during + // UI fade + Script.setTimeout(function () { + setTabletVisibleInSecondaryCamera(true); + DesktopPreviewProvider.setPreviewDisabledReason("USER"); + Menu.setIsOptionChecked("Disable Preview", savedDisablePreviewOption); + savedDisablePreviewOptionLocked = false; + }, 150); } // Function Name: fromQml() From c3ef6aab1c96158ea4edb67f188da9e39c2f69be Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 7 May 2018 12:51:41 -0700 Subject: [PATCH 072/152] Don't save test scripts --- libraries/script-engine/src/ScriptEngine.h | 5 +++++ libraries/script-engine/src/ScriptEngines.cpp | 15 ++++----------- libraries/script-engine/src/ScriptEngines.h | 4 ++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 7a9af2278c..3001666b5d 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -526,6 +526,9 @@ public: void setUserLoaded(bool isUserLoaded) { _isUserLoaded = isUserLoaded; } bool isUserLoaded() const { return _isUserLoaded; } + void setQuitWhenFinished(const bool quitWhenFinished) { _quitWhenFinished = quitWhenFinished; } + bool isQuitWhenFinished() const { return _quitWhenFinished; } + // NOTE - this is used by the TypedArray implementation. we need to review this for thread safety ArrayBufferClass* getArrayBufferClass() { return _arrayBufferClass; } @@ -768,6 +771,8 @@ protected: std::atomic _isUserLoaded { false }; bool _isReloading { false }; + std::atomic _quitWhenFinished; + ArrayBufferClass* _arrayBufferClass; AssetScriptingInterface* _assetScriptingInterface; diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index d2834e8c4a..b5a7cff0ab 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -347,7 +347,8 @@ void ScriptEngines::saveScripts() { { QReadLocker lock(&_scriptEnginesHashLock); for (auto it = _scriptEnginesHash.begin(); it != _scriptEnginesHash.end(); ++it) { - if (it.value() && it.value()->isUserLoaded()) { + // Save user-loaded scripts, only if they are set to quit when finished + if (it.value() && it.value()->isUserLoaded() && !it.value()->isQuitWhenFinished()) { auto normalizedUrl = normalizeScriptURL(it.key()); list.append(normalizedUrl.toString()); } @@ -456,7 +457,7 @@ void ScriptEngines::reloadAllScripts() { } ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor, - bool activateMainWindow, bool reload, bool exitWhenFinished) { + bool activateMainWindow, bool reload, bool quitWhenFinished) { if (thread() != QThread::currentThread()) { ScriptEnginePointer result { nullptr }; BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(ScriptEnginePointer, result), @@ -488,6 +489,7 @@ ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool i scriptEngine = ScriptEnginePointer(new ScriptEngine(_context, NO_SCRIPT, "about:" + scriptFilename.fileName())); addScriptEngine(scriptEngine); scriptEngine->setUserLoaded(isUserLoaded); + scriptEngine->setQuitWhenFinished(quitWhenFinished); if (scriptFilename.isEmpty() || !scriptUrl.isValid()) { launchScriptEngine(scriptEngine); @@ -496,11 +498,6 @@ ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool i connect(scriptEngine.data(), &ScriptEngine::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded); connect(scriptEngine.data(), &ScriptEngine::errorLoadingScript, this, &ScriptEngines::onScriptEngineError); - // Shutdown Interface when script finishes, if requested - if (exitWhenFinished) { - connect(scriptEngine.data(), &ScriptEngine::finished, this, &ScriptEngines::exitWhenFinished); - } - // get the script engine object to load the script at the designated script URL scriptEngine->loadURL(scriptUrl, reload); } @@ -541,10 +538,6 @@ void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { emit scriptCountChanged(); } -void ScriptEngines::exitWhenFinished() { - qApp->quit(); -} - int ScriptEngines::runScriptInitializers(ScriptEnginePointer scriptEngine) { int ii=0; for (auto initializer : _scriptInitializers) { diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index 6f88e8978d..51eec8ab3e 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -88,10 +88,11 @@ public: * @param {boolean} [loadScriptFromEditor=false] * @param {boolean} [activateMainWindow=false] * @param {boolean} [reload=false] + * @param {boolean} [quitWhenFinished=false] * @returns {boolean} */ Q_INVOKABLE ScriptEnginePointer loadScript(const QUrl& scriptFilename = QString(), - bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false, bool exitWhenFinished = false); + bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false, bool quitWhenFinished = false); /**jsdoc * @function ScriptDiscoveryService.stopScript @@ -266,7 +267,6 @@ protected: ScriptEnginePointer reloadScript(const QString& scriptName, bool isUserLoaded = true) { return loadScript(scriptName, isUserLoaded, false, false, true); } void removeScriptEngine(ScriptEnginePointer); void onScriptEngineLoaded(const QString& scriptFilename); - void exitWhenFinished(); void onScriptEngineError(const QString& scriptFilename); void launchScriptEngine(ScriptEnginePointer); From 2e51a66441cc89e21337b7c38774b234b094872c Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 7 May 2018 13:01:18 -0700 Subject: [PATCH 073/152] Use 'standard' format for command line parameter with multiple options. --- interface/src/Application.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8ee577c282..bb04c3bf40 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -744,9 +744,9 @@ extern InputPluginList getInputPlugins(); extern void saveInputPluginSettings(const InputPluginList& plugins); // Parameters used for running tests from teh command line -const QString TEST_SCRIPT { "--testScript" }; -const QString TEST_QUIT_WHEN_FINISHED { "--quitWhenFinished" }; -const QString TEST_SNAPSHOT_LOCATION { "--testSnapshotLocation" }; +const QString TEST_SCRIPT_COMMAND { "--testScript" }; +const QString TEST_QUIT_WHEN_FINISHED_OPTION { "quitWhenFinished" }; +const QString TEST_SNAPSHOT_LOCATION_COMMAND { "--testSnapshotLocation" }; bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { const char** constArgv = const_cast(argv); @@ -787,7 +787,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { bool inTestMode { false }; for (int i = 0; i < argc; ++i) { QString parameter(argv[i]); - if (parameter == TEST_SCRIPT) { + if (parameter == TEST_SCRIPT_COMMAND) { inTestMode = true; break; } @@ -1019,7 +1019,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo const QStringList args = arguments(); for (int i = 0; i < args.size() - 1; ++i) { - if (args.at(i) == TEST_SCRIPT && (i + 1) < args.size()) { + if (args.at(i) == TEST_SCRIPT_COMMAND && (i + 1) < args.size()) { QString testScriptPath = args.at(i + 1); // If the URL scheme is "http(s)" then use as is, else - treat it as a local file @@ -1031,10 +1031,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } // quite when finished parameter must directly follow the test script - if ((i + 2) < args.size() && args.at(i + 2) == TEST_QUIT_WHEN_FINISHED) { + if ((i + 2) < args.size() && args.at(i + 2) == TEST_QUIT_WHEN_FINISHED_OPTION) { quitWhenFinished = true; } - } else if (args.at(i) == TEST_SNAPSHOT_LOCATION) { + } else if (args.at(i) == TEST_SNAPSHOT_LOCATION_COMMAND) { // Set test snapshot location only if it is a writeable directory QString pathname(args.at(i + 1)); QFileInfo fileInfo(pathname); From fd4530e671b96d17af052ef7882fc674800a66f6 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 7 May 2018 14:39:31 -0700 Subject: [PATCH 074/152] MS3128: Remove vestigal Edit menu item --- scripts/system/edit.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 6bb815a597..523582836f 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1165,17 +1165,11 @@ function setupModelMenus() { }); modelMenuAddedDelete = true; } - Menu.addMenuItem({ - menuName: "Edit", - menuItemName: "Entity List...", - afterItem: "Entities", - grouping: "Advanced" - }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Parent Entity to Last", - afterItem: "Entity List...", + afterItem: "Entities", grouping: "Advanced" }); @@ -1297,7 +1291,6 @@ function cleanupModelMenus() { Menu.removeMenuItem("Edit", "Parent Entity to Last"); Menu.removeMenuItem("Edit", "Unparent Entity"); - Menu.removeMenuItem("Edit", "Entity List..."); Menu.removeMenuItem("Edit", "Allow Selecting of Large Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Small Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Lights"); @@ -1659,8 +1652,6 @@ function handeMenuEvent(menuItem) { Window.promptTextChanged.connect(onPromptTextChanged); Window.promptAsync("URL of SVO to import", ""); } - } else if (menuItem === "Entity List...") { - entityListTool.toggleVisible(); } else if (menuItem === "Select All Entities In Box") { selectAllEtitiesInCurrentSelectionBox(false); } else if (menuItem === "Select All Entities Touching Box") { From a593209ec132ee828f454d6f505ee7ee9cc0ea38 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 7 May 2018 15:30:17 -0700 Subject: [PATCH 075/152] remove highlight when point to the sky --- .../controllers/controllerModules/farActionGrabEntity.js | 3 +++ .../controllers/controllerModules/mouseHighlightEntities.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index cc884cdbc7..66cd197abd 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -564,6 +564,9 @@ Script.include("/~/system/libraries/Xform.js"); } } else if (this.distanceRotating) { this.distanceRotate(otherFarGrabModule); + } else if (this.highlightedEntity) { + Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); + this.highlightedEntity = null; } } return this.exitIfDisabled(controllerData); diff --git a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js index 3180e58e2c..ac57c8691f 100644 --- a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js +++ b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js @@ -63,6 +63,9 @@ this.highlightedEntity = targetEntityID; } } + } else if (this.highlightedEntity) { + dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity); + this.highlightedEntity = null; } } From eb14658bc554c58e72e40474bbb7bdc328570d83 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 8 May 2018 11:13:06 -0700 Subject: [PATCH 076/152] Per Austin's comments. --- interface/src/Application.cpp | 4 +- tools/auto-tester/src/Downloader.cpp | 5 +-- tools/auto-tester/src/Test.cpp | 54 +++++++++++++------------ tools/auto-tester/src/Test.h | 2 - tools/auto-tester/src/ui/AutoTester.cpp | 3 +- 5 files changed, 33 insertions(+), 35 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8d1db32cdd..544d767370 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1022,9 +1022,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (args.at(i) == TEST_SCRIPT_COMMAND && (i + 1) < args.size()) { QString testScriptPath = args.at(i + 1); - // If the URL scheme is "http(s)" then use as is, else - treat it as a local file + // If the URL scheme is http(s) or ftp, then use as is, else - treat it as a local file // This is done so as not break previous command line scripts - if (testScriptPath.left(4) == "http") { + if (testScriptPath.left(URL_SCHEME_HTTP.length()) == URL_SCHEME_HTTP || testScriptPath.left(URL_SCHEME_FTP.length()) == URL_SCHEME_FTP) { setProperty(hifi::properties::TEST, QUrl::fromUserInput(testScriptPath)); } else if (QFileInfo(testScriptPath).exists()) { setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); diff --git a/tools/auto-tester/src/Downloader.cpp b/tools/auto-tester/src/Downloader.cpp index e66b498bd5..530a3b61bd 100644 --- a/tools/auto-tester/src/Downloader.cpp +++ b/tools/auto-tester/src/Downloader.cpp @@ -9,7 +9,7 @@ // #include "Downloader.h" -#include +#include Downloader::Downloader(QUrl imageUrl, QObject *parent) : QObject(parent) { connect( @@ -24,8 +24,7 @@ Downloader::Downloader(QUrl imageUrl, QObject *parent) : QObject(parent) { void Downloader::fileDownloaded(QNetworkReply* reply) { QNetworkReply::NetworkError error = reply->error(); if (error != QNetworkReply::NetworkError::NoError) { - QMessageBox messageBox; - messageBox.information(0, "Test Aborted", "Failed to download image: " + reply->errorString()); + QMessageBox::information(0, "Test Aborted", "Failed to download image: " + reply->errorString()); return; } diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index e00bc920e5..0eec03a782 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -72,7 +72,7 @@ bool Test::compareImageLists(bool isInteractiveMode, QProgressBar* progressBar) QImage expectedImage(expectedImagesFullFilenames[i]); if (resultImage.width() != expectedImage.width() || resultImage.height() != expectedImage.height()) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Images are not the same size"); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Images are not the same size"); exit(-1); } @@ -80,7 +80,7 @@ bool Test::compareImageLists(bool isInteractiveMode, QProgressBar* progressBar) try { similarityIndex = imageComparer.compareImages(resultImage, expectedImage); } catch (...) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Image not in expected format"); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Image not in expected format"); exit(-1); } @@ -127,20 +127,20 @@ bool Test::compareImageLists(bool isInteractiveMode, QProgressBar* progressBar) void Test::appendTestResultsToFile(const QString& testResultsFolderPath, TestFailure testFailure, QPixmap comparisonImage) { if (!QDir().exists(testResultsFolderPath)) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Folder " + testResultsFolderPath + " not found"); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Folder " + testResultsFolderPath + " not found"); exit(-1); } QString failureFolderPath { testResultsFolderPath + "/" + "Failure_" + QString::number(index) }; if (!QDir().mkdir(failureFolderPath)) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create folder " + failureFolderPath); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create folder " + failureFolderPath); exit(-1); } ++index; QFile descriptionFile(failureFolderPath + "/" + TEST_RESULTS_FILENAME); if (!descriptionFile.open(QIODevice::ReadWrite)) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + TEST_RESULTS_FILENAME); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + TEST_RESULTS_FILENAME); exit(-1); } @@ -160,14 +160,14 @@ void Test::appendTestResultsToFile(const QString& testResultsFolderPath, TestFai sourceFile = testFailure._pathname + testFailure._expectedImageFilename; destinationFile = failureFolderPath + "/" + "Expected Image.jpg"; if (!QFile::copy(sourceFile, destinationFile)) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to copy " + sourceFile + " to " + destinationFile); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to copy " + sourceFile + " to " + destinationFile); exit(-1); } sourceFile = testFailure._pathname + testFailure._actualImageFilename; destinationFile = failureFolderPath + "/" + "Actual Image.jpg"; if (!QFile::copy(sourceFile, destinationFile)) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to copy " + sourceFile + " to " + destinationFile); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to copy " + sourceFile + " to " + destinationFile); exit(-1); } @@ -248,9 +248,9 @@ void Test::finishTestsEvaluation(bool isRunningFromCommandline, bool interactive if (!isRunningFromCommandline) { if (success) { - messageBox.information(0, "Success", "All images are as expected"); + QMessageBox::information(0, "Success", "All images are as expected"); } else { - messageBox.information(0, "Failure", "One or more images are not as expected"); + QMessageBox::information(0, "Failure", "One or more images are not as expected"); } } @@ -281,7 +281,7 @@ QString Test::extractPathFromTestsDown(const QString& fullPath) { } if (i == pathParts.length()) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Bad testPathname"); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Bad testPathname"); exit(-1); } @@ -350,14 +350,14 @@ void Test::createAllRecursiveScripts() { } } - messageBox.information(0, "Success", "Scripts have been created"); + QMessageBox::information(0, "Success", "Scripts have been created"); } void Test::createRecursiveScript(const QString& topLevelDirectory, bool interactiveMode) { const QString recursiveTestsFilename("testRecursive.js"); QFile allTestsFilename(topLevelDirectory + "/" + recursiveTestsFilename); if (!allTestsFilename.open(QIODevice::WriteOnly | QIODevice::Text)) { - messageBox.critical(0, + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create \"" + recursiveTestsFilename + "\" in directory \"" + topLevelDirectory + "\"" ); @@ -366,7 +366,9 @@ void Test::createRecursiveScript(const QString& topLevelDirectory, bool interact } QTextStream textStream(&allTestsFilename); - textStream << "// This is an automatically generated file, created by auto-tester on " << __DATE__ << ", " << __TIME__ << endl << endl; + + const QString DATE_TIME_FORMAT("MMM d yyyy, h:mm"); + textStream << "// This is an automatically generated file, created by auto-tester on " << QDateTime::currentDateTime().toString(DATE_TIME_FORMAT) << endl << endl; textStream << "var autoTester = Script.require(\"https://github.com/" + githubUser + "/hifi_tests/blob/" + gitHubBranch + "/tests/utils/autoTester.js?raw=true\");" << endl << endl; @@ -407,7 +409,7 @@ void Test::createRecursiveScript(const QString& topLevelDirectory, bool interact } if (interactiveMode && testPathnames.length() <= 0) { - messageBox.information(0, "Failure", "No \"" + TEST_FILENAME + "\" files found"); + QMessageBox::information(0, "Failure", "No \"" + TEST_FILENAME + "\" files found"); allTestsFilename.close(); return; } @@ -418,7 +420,7 @@ void Test::createRecursiveScript(const QString& topLevelDirectory, bool interact allTestsFilename.close(); if (interactiveMode) { - messageBox.information(0, "Success", "Script has been created"); + QMessageBox::information(0, "Success", "Script has been created"); } } @@ -443,7 +445,7 @@ void Test::createTest() { QString fullCurrentFilename = imageSourceDirectory + "/" + currentFilename; if (isInSnapshotFilenameFormat("jpg", currentFilename)) { if (i >= maxImages) { - messageBox.critical(0, "Error", "More than " + QString::number(maxImages) + " images not supported"); + QMessageBox::critical(0, "Error", "More than " + QString::number(maxImages) + " images not supported"); exit(-1); } QString newFilename = "ExpectedImage_" + QString::number(i - 1).rightJustified(5, '0') + ".png"; @@ -452,14 +454,14 @@ void Test::createTest() { try { copyJPGtoPNG(fullCurrentFilename, fullNewFileName); } catch (...) { - messageBox.critical(0, "Error", "Could not delete existing file: " + currentFilename + "\nTest creation aborted"); + QMessageBox::critical(0, "Error", "Could not delete existing file: " + currentFilename + "\nTest creation aborted"); exit(-1); } ++i; } } - messageBox.information(0, "Success", "Test images have been created"); + QMessageBox::information(0, "Success", "Test images have been created"); } ExtractedText Test::getTestScriptLines(QString testFileName) { @@ -468,7 +470,7 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { QFile inputFile(testFileName); inputFile.open(QIODevice::ReadOnly); if (!inputFile.isOpen()) { - messageBox.critical(0, + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to open \"" + testFileName ); @@ -598,7 +600,7 @@ void Test::createAllMDFiles() { } } - messageBox.information(0, "Success", "MD files have been created"); + QMessageBox::information(0, "Success", "MD files have been created"); } void Test::createMDFile(const QString& testDirectory) { @@ -606,7 +608,7 @@ void Test::createMDFile(const QString& testDirectory) { QString testFileName(testDirectory + "/" + TEST_FILENAME); QFileInfo testFileInfo(testFileName); if (!testFileInfo.exists()) { - messageBox.critical(0, "Error", "Could not find file: " + TEST_FILENAME); + QMessageBox::critical(0, "Error", "Could not find file: " + TEST_FILENAME); return; } @@ -615,7 +617,7 @@ void Test::createMDFile(const QString& testDirectory) { QString mdFilename(testDirectory + "/" + "test.md"); QFile mdFile(mdFilename); if (!mdFile.open(QIODevice::WriteOnly)) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + mdFilename); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + mdFilename); exit(-1); } @@ -650,7 +652,7 @@ void Test::createMDFile(const QString& testDirectory) { mdFile.close(); - messageBox.information(0, "Success", "Test MD file " + mdFilename + " has been created"); + QMessageBox::information(0, "Success", "Test MD file " + mdFilename + " has been created"); } void Test::createTestsOutline() { @@ -663,7 +665,7 @@ void Test::createTestsOutline() { QString mdFilename(testsRootDirectory + "/" + testsOutlineFilename); QFile mdFile(mdFilename); if (!mdFile.open(QIODevice::WriteOnly)) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + mdFilename); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + mdFilename); exit(-1); } @@ -721,7 +723,7 @@ void Test::createTestsOutline() { mdFile.close(); - messageBox.information(0, "Success", "Test outline file " + testsOutlineFilename + " has been created"); + QMessageBox::information(0, "Success", "Test outline file " + testsOutlineFilename + " has been created"); } void Test::copyJPGtoPNG(const QString& sourceJPGFullFilename, const QString& destinationPNGFullFilename) { @@ -796,7 +798,7 @@ QString Test::getExpectedImagePartialSourceDirectory(const QString& filename) { } if (i < 0) { - messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Bad filename"); + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Bad filename"); exit(-1); } diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index b341c1d00f..bc28d6ad0a 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -76,8 +76,6 @@ private: const QString TEST_RESULTS_FOLDER { "TestResults" }; const QString TEST_RESULTS_FILENAME { "TestResults.txt" }; - QMessageBox messageBox; - QDir imageDirectory; MismatchWindow mismatchWindow; diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index 59fe5d9de2..8fd81efc1f 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -115,6 +115,5 @@ void AutoTester::saveImage(int index) { } void AutoTester::about() { - QMessageBox messageBox; - messageBox.information(0, "About", QString("Built ") + __DATE__ + " : " + __TIME__); + QMessageBox::information(0, "About", QString("Built ") + __DATE__ + " : " + __TIME__); } From d5bb582811dd8f73d68e06add7b4589c766b25b7 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 8 May 2018 11:40:56 -0700 Subject: [PATCH 077/152] Per Austin's comments. --- interface/src/ui/Snapshot.cpp | 2 +- interface/src/ui/Snapshot.h | 5 ++++- tools/auto-tester/src/ui/AutoTester.cpp | 3 +-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 73ea8398e7..39fef1d742 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -90,7 +90,7 @@ QString Snapshot::saveSnapshot(QImage image, const QString& filename, const QStr QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { // return whatever we get back from saved file for snapshot - return static_cast(savedFileForSnapshot(image, true, QString(), QString())); + return static_cast(savedFileForSnapshot(image, true)); } QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename, const QString& userSelectedPathname) { diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index aad63d1037..606313f3c3 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -52,7 +52,10 @@ public slots: Q_INVOKABLE QString getSnapshotsLocation(); Q_INVOKABLE void setSnapshotsLocation(const QString& location); private: - static QFile* savedFileForSnapshot(QImage & image, bool isTemporary, const QString& userSelectedFilename, const QString& userSelectedPathname); + static QFile* savedFileForSnapshot(QImage& image, + bool isTemporary, + const QString& userSelectedFilename = QString(), + const QString& userSelectedPathname = QString()); }; #endif // hifi_Snapshot_h diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index 8fd81efc1f..db9974a250 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -99,8 +99,7 @@ void AutoTester::saveImage(int index) { QString fullPathname = _directoryName + "/" + _filenames[index]; if (!image.save(fullPathname, 0, 100)) { - QMessageBox messageBox; - messageBox.information(0, "Test Aborted", "Failed to save image: " + _filenames[index]); + QMessageBox::information(0, "Test Aborted", "Failed to save image: " + _filenames[index]); ui.progressBar->setVisible(false); return; } From da69c9d077d7d1c7f322dc66eed23bf16b1bcd25 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Tue, 8 May 2018 15:45:33 -0300 Subject: [PATCH 078/152] Make qt application not stop in background and remove separete thread --- .../hifiinterface/InterfaceActivity.java | 6 ++---- .../qt5/android/bindings/QtActivity.java | 4 ++-- interface/src/AndroidHelper.cpp | 21 +++++++++---------- interface/src/AndroidHelper.h | 4 +++- interface/src/Application.cpp | 16 +++++++------- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java index 8a2f8cd030..2b3e0dea5e 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java @@ -130,15 +130,13 @@ public class InterfaceActivity extends QtActivity { if (!isLoading) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } - // TODO Fix displayPlugin deactivate so it doesn't leave us with a black screen Interface - //nativeEnterForeground(); + nativeEnterForeground(); } @Override protected void onStop() { super.onStop(); - // TODO Fix displayPlugin deactivate so it doesn't leave us with a black screen Interface - //nativeEnterBackground(); + nativeEnterBackground(); } @Override diff --git a/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java b/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java index 887d27dba4..0639c66f38 100644 --- a/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java @@ -504,7 +504,7 @@ public class QtActivity extends Activity { // GC: this trick allow us to show a splash activity until Qt app finishes // loading if (!isLoading) { - QtApplication.invokeDelegate(); + //QtApplication.invokeDelegate(); } } //--------------------------------------------------------------------------- @@ -644,7 +644,7 @@ public class QtActivity extends Activity { @Override protected void onStop() { super.onStop(); - QtApplication.invokeDelegate(); + //QtApplication.invokeDelegate(); } //--------------------------------------------------------------------------- diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp index 9b79881075..10745b71ab 100644 --- a/interface/src/AndroidHelper.cpp +++ b/interface/src/AndroidHelper.cpp @@ -14,22 +14,13 @@ AndroidHelper::AndroidHelper() : _accountManager () { - workerThread.start(); } AndroidHelper::~AndroidHelper() { - workerThread.quit(); - workerThread.wait(); } QSharedPointer AndroidHelper::getAccountManager() { - - _accountManager = QSharedPointer(new AccountManager, &QObject::deleteLater); - _accountManager->setIsAgent(true); - _accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL()); - _accountManager->moveToThread(&workerThread); - - return _accountManager; + return DependencyManager::get(); } void AndroidHelper::requestActivity(const QString &activityName) { @@ -46,4 +37,12 @@ void AndroidHelper::goBackFromAndroidActivity() { void AndroidHelper::notifyLoginComplete(bool success) { emit loginComplete(success); -} \ No newline at end of file +} + +void AndroidHelper::setInBackground(bool background) { + inBackground = background; +} + +bool AndroidHelper::isInBackground() { + return inBackground; +} diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h index dafb4ca89e..51ef51ee4f 100644 --- a/interface/src/AndroidHelper.h +++ b/interface/src/AndroidHelper.h @@ -26,6 +26,8 @@ public: void requestActivity(const QString &activityName); void notifyLoadComplete(); void goBackFromAndroidActivity(); + void setInBackground(bool background); + bool isInBackground(); void notifyLoginComplete(bool success); @@ -44,7 +46,7 @@ private: AndroidHelper(); ~AndroidHelper(); QSharedPointer _accountManager; - QThread workerThread; + bool inBackground; }; #endif \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 37e6628543..46d06f6443 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4331,6 +4331,12 @@ void setupCpuMonitorThread() { void Application::idle() { PerformanceTimer perfTimer("idle"); +#if defined(Q_OS_ANDROID) + if (AndroidHelper::instance().isInBackground()) { + return; + } +#endif + // Update the deadlock watchdog updateHeartbeat(); @@ -8177,17 +8183,13 @@ void Application::openAndroidActivity(const QString& activityName) { void Application::enterBackground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "stop", Qt::BlockingQueuedConnection); - //GC: commenting it out until we fix it - //getActiveDisplayPlugin()->deactivate(); + AndroidHelper::instance().setInBackground(true); } + void Application::enterForeground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "start", Qt::BlockingQueuedConnection); - //GC: commenting it out until we fix it - /*if (!getActiveDisplayPlugin() || !getActiveDisplayPlugin()->activate()) { - qWarning() << "Could not re-activate display plugin"; - }*/ - + AndroidHelper::instance().setInBackground(false); } #endif From 5e337e90a328e8fff3542ad795a759f07e3ed865 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Tue, 8 May 2018 16:55:04 -0300 Subject: [PATCH 079/152] Deactivates display plugin when qt app goes to background --- .../highfidelity/hifiinterface/SplashActivity.java | 7 ++----- interface/src/AndroidHelper.cpp | 12 +----------- interface/src/AndroidHelper.h | 4 ---- interface/src/Application.cpp | 14 +++++--------- 4 files changed, 8 insertions(+), 29 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java index 08f8615a16..893c13f337 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java @@ -27,10 +27,7 @@ public class SplashActivity extends Activity { } public void onAppLoadedComplete() { - // Give interface more time so textures don't fail(got deleted) on Adreno (joystick) - new Handler(getMainLooper()).postDelayed(() -> { - startActivity(new Intent(this, HomeActivity.class)); - new Handler(getMainLooper()).postDelayed(() -> SplashActivity.this.finish(), 1000); - }, 500); + startActivity(new Intent(this, HomeActivity.class)); + finish(); } } diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp index 10745b71ab..339d2532a6 100644 --- a/interface/src/AndroidHelper.cpp +++ b/interface/src/AndroidHelper.cpp @@ -11,9 +11,7 @@ #include "AndroidHelper.h" #include -AndroidHelper::AndroidHelper() : -_accountManager () -{ +AndroidHelper::AndroidHelper() { } AndroidHelper::~AndroidHelper() { @@ -38,11 +36,3 @@ void AndroidHelper::goBackFromAndroidActivity() { void AndroidHelper::notifyLoginComplete(bool success) { emit loginComplete(success); } - -void AndroidHelper::setInBackground(bool background) { - inBackground = background; -} - -bool AndroidHelper::isInBackground() { - return inBackground; -} diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h index 51ef51ee4f..b9f7407453 100644 --- a/interface/src/AndroidHelper.h +++ b/interface/src/AndroidHelper.h @@ -26,8 +26,6 @@ public: void requestActivity(const QString &activityName); void notifyLoadComplete(); void goBackFromAndroidActivity(); - void setInBackground(bool background); - bool isInBackground(); void notifyLoginComplete(bool success); @@ -45,8 +43,6 @@ signals: private: AndroidHelper(); ~AndroidHelper(); - QSharedPointer _accountManager; - bool inBackground; }; #endif \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 46d06f6443..e82a6d9965 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4330,13 +4330,7 @@ void setupCpuMonitorThread() { void Application::idle() { PerformanceTimer perfTimer("idle"); - -#if defined(Q_OS_ANDROID) - if (AndroidHelper::instance().isInBackground()) { - return; - } -#endif - + // Update the deadlock watchdog updateHeartbeat(); @@ -8183,13 +8177,15 @@ void Application::openAndroidActivity(const QString& activityName) { void Application::enterBackground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "stop", Qt::BlockingQueuedConnection); - AndroidHelper::instance().setInBackground(true); + getActiveDisplayPlugin()->deactivate(); } void Application::enterForeground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "start", Qt::BlockingQueuedConnection); - AndroidHelper::instance().setInBackground(false); + if (!getActiveDisplayPlugin() || !getActiveDisplayPlugin()->activate()) { + qWarning() << "Could not re-activate display plugin"; + } } #endif From f21ef30d85b246e08df85d8d6aec9fa6652bcfe3 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Tue, 8 May 2018 17:24:49 -0300 Subject: [PATCH 080/152] Restore back the fix for joystick texture corruption --- .../java/io/highfidelity/hifiinterface/SplashActivity.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java index 893c13f337..08f8615a16 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java @@ -27,7 +27,10 @@ public class SplashActivity extends Activity { } public void onAppLoadedComplete() { - startActivity(new Intent(this, HomeActivity.class)); - finish(); + // Give interface more time so textures don't fail(got deleted) on Adreno (joystick) + new Handler(getMainLooper()).postDelayed(() -> { + startActivity(new Intent(this, HomeActivity.class)); + new Handler(getMainLooper()).postDelayed(() -> SplashActivity.this.finish(), 1000); + }, 500); } } From 0513204781cc4104faf3d0fd4d35b2c034d0a47f Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 8 May 2018 15:05:55 -0700 Subject: [PATCH 081/152] fix hmd.js --- scripts/system/hmd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/hmd.js b/scripts/system/hmd.js index b9fd7f725c..bf1e048bc4 100644 --- a/scripts/system/hmd.js +++ b/scripts/system/hmd.js @@ -18,7 +18,7 @@ var headset; // The preferred headset. Default to the first one found in the following list. var displayMenuName = "Display"; var desktopMenuItemName = "Desktop"; -['OpenVR (Vive)', 'Oculus Rift'].forEach(function (name) { +['HTC Vive', 'Oculus Rift'].forEach(function (name) { if (!headset && Menu.menuItemExists(displayMenuName, name)) { headset = name; } From 1a0ded4526d7f37fd4ce25df4567b249c4859a65 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 8 May 2018 15:10:57 -0700 Subject: [PATCH 082/152] adding windows --- scripts/system/hmd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/hmd.js b/scripts/system/hmd.js index bf1e048bc4..2d4a2d3e97 100644 --- a/scripts/system/hmd.js +++ b/scripts/system/hmd.js @@ -18,7 +18,7 @@ var headset; // The preferred headset. Default to the first one found in the following list. var displayMenuName = "Display"; var desktopMenuItemName = "Desktop"; -['HTC Vive', 'Oculus Rift'].forEach(function (name) { +['HTC Vive', 'Oculus Rift', 'WindowMS'].forEach(function (name) { if (!headset && Menu.menuItemExists(displayMenuName, name)) { headset = name; } From 7f9f9d769adfe5e96159ae1c836322dcb643acb7 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 8 May 2018 15:51:52 -0700 Subject: [PATCH 083/152] Corrected bug causing Interface not to exit at end of test. --- libraries/script-engine/src/ScriptEngines.cpp | 9 +++++++++ libraries/script-engine/src/ScriptEngines.h | 1 + 2 files changed, 10 insertions(+) diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index b5a7cff0ab..ad6e1debe9 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -498,6 +498,11 @@ ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool i connect(scriptEngine.data(), &ScriptEngine::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded); connect(scriptEngine.data(), &ScriptEngine::errorLoadingScript, this, &ScriptEngines::onScriptEngineError); + // Shutdown Interface when script finishes, if requested + if (quitWhenFinished) { + connect(scriptEngine.data(), &ScriptEngine::finished, this, &ScriptEngines::quitWhenFinished); + } + // get the script engine object to load the script at the designated script URL scriptEngine->loadURL(scriptUrl, reload); } @@ -538,6 +543,10 @@ void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { emit scriptCountChanged(); } +void ScriptEngines::quitWhenFinished() { + qApp->quit(); +} + int ScriptEngines::runScriptInitializers(ScriptEnginePointer scriptEngine) { int ii=0; for (auto initializer : _scriptInitializers) { diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index 51eec8ab3e..4d5964e462 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -267,6 +267,7 @@ protected: ScriptEnginePointer reloadScript(const QString& scriptName, bool isUserLoaded = true) { return loadScript(scriptName, isUserLoaded, false, false, true); } void removeScriptEngine(ScriptEnginePointer); void onScriptEngineLoaded(const QString& scriptFilename); + void quitWhenFinished(); void onScriptEngineError(const QString& scriptFilename); void launchScriptEngine(ScriptEnginePointer); From 44e7541888d203cd79ba2f06a079b3cdaf382ded Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 8 May 2018 15:57:27 -0700 Subject: [PATCH 084/152] Fixing the size evaluation for compressed texture and gpu::Element Type enum --- libraries/gpu/src/gpu/Format.h | 73 ++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index d4e4a89636..7a3e0a2f82 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -50,47 +50,50 @@ enum Type : uint8_t { }; // Array providing the size in bytes for a given scalar type static const int TYPE_SIZE[NUM_TYPES] = { - 4, - 4, - 4, - 2, - 2, - 2, - 1, - 1, + 4, // FLOAT + 4, // INT32 + 4, // UINT32 + 2, // HALF + 2, // INT16 + 2, // UINT16 + 1, // INT8 + 1, // UINT8 // normalized values - 4, - 4, - 2, - 2, - 1, - 1, - 4, + 4, // NINT32 + 4, // NUINT32 + 2, // NINT16 + 2, // NUINT16 + 1, // NINT8 + 1, // NUINT8 + 1, // NUINT2 + 1, // NINT2_10_10_10 - 1 + 1, // COMPRESSED }; + // Array answering the question Does this type is integer or not static const bool TYPE_IS_INTEGER[NUM_TYPES] = { - false, - true, - true, - false, - true, - true, - true, - true, + false, // FLOAT + true, // INT32 + true, // UINT32 + false, // HALF + true, // INT16 + true, // UINT16 + true, // INT8 + true, // UINT8 // Normalized values - false, - false, - false, - false, - false, - false, - false, + false, // NINT32 + false, // NUINT32 + false, // NINT16 + false, // NUINT16 + false, // NINT8 + false, // NUINT8 + false, // NUINT2 + false, // NINT2_10_10_10 - false, + false, // COMPRESSED }; // Dimension of an Element @@ -367,9 +370,9 @@ public: static const Element PART_DRAWCALL; protected: - uint8 _semantic; - uint8 _dimension : 4; - uint8 _type : 4; + uint16 _semantic : 7; + uint16 _dimension : 4; + uint16 _type : 5; }; From 540f200b99a6df817799bb9b1f29588985c939ef Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 8 May 2018 16:34:28 -0700 Subject: [PATCH 085/152] MS14937: Fix Replace button for content sets during Checkout --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 1cfbcf9075..f25282c738 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -787,7 +787,7 @@ Rectangle { } lightboxPopup.button2text = "CONFIRM"; lightboxPopup.button2method = function() { - Commerce.replaceContentSet(root.itemHref); + Commerce.replaceContentSet(root.itemHref, root.certificateId); lightboxPopup.visible = false; rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); From 22c26c348dcf39d313a631ab2f52e80e33c7dee4 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 8 May 2018 16:34:28 -0700 Subject: [PATCH 086/152] MS14937: Fix Replace button for content sets during Checkout --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 1cfbcf9075..f25282c738 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -787,7 +787,7 @@ Rectangle { } lightboxPopup.button2text = "CONFIRM"; lightboxPopup.button2method = function() { - Commerce.replaceContentSet(root.itemHref); + Commerce.replaceContentSet(root.itemHref, root.certificateId); lightboxPopup.visible = false; rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); From ee4b1af3aa4ff93eb1348fb5d8a924b49237a9e2 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 8 May 2018 16:51:58 -0700 Subject: [PATCH 087/152] Corrected missing images in test.md files --- tools/auto-tester/src/Test.cpp | 76 ---------------------------------- tools/auto-tester/src/Test.h | 4 -- 2 files changed, 80 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index 99f9025fdd..bdf734897e 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -478,26 +478,6 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { QString regexTestTitle(ws + functionPerformName + "\\(" + quotedString + "\\," + ws + ownPath + "\\," + ws + functionParameter + ws + "{" + ".*"); QRegularExpression lineContainingTitle = QRegularExpression(regexTestTitle); - // Assert platform checks that test is running on the correct OS - const QString functionAssertPlatform(ws + "autoTester" + ws + "\\." + ws + "assertPlatform"); - const QString regexAssertPlatform(ws + functionAssertPlatform + ws + "\\(" + ws + quotedString + ".*"); - const QRegularExpression lineAssertPlatform = QRegularExpression(regexAssertPlatform); - - // Assert display checks that test is running on the correct display - const QString functionAssertDisplay(ws + "autoTester" + ws + "\\." + ws + "assertDisplay"); - const QString regexAssertDisplay(ws + functionAssertDisplay + ws + "\\(" + ws + quotedString + ".*"); - const QRegularExpression lineAssertDisplay = QRegularExpression(regexAssertDisplay); - - // Assert CPU checks that test is running on the correct type of CPU - const QString functionAssertCPU(ws + "autoTester" + ws + "\\." + ws + "assertCPU"); - const QString regexAssertCPU(ws + functionAssertCPU + ws + "\\(" + ws + quotedString + ".*"); - const QRegularExpression lineAssertCPU = QRegularExpression(regexAssertCPU); - - // Assert GPU checks that test is running on the correct type of GPU - const QString functionAssertGPU(ws + "autoTester" + ws + "\\." + ws + "assertGPU"); - const QString regexAssertGPU(ws + functionAssertGPU + ws + "\\(" + ws + quotedString + ".*"); - const QRegularExpression lineAssertGPU = QRegularExpression(regexAssertGPU); - // Each step is either of the following forms: // autoTester.addStepSnapshot("Take snapshot"... // autoTester.addStep("Clean up after test"... @@ -514,18 +494,6 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { if (lineContainingTitle.match(line).hasMatch()) { QStringList tokens = line.split('"'); relevantTextFromTest.title = tokens[1]; - } else if (lineAssertPlatform.match(line).hasMatch()) { - QStringList platforms = line.split('"'); - relevantTextFromTest.platform = platforms[1]; - } else if (lineAssertDisplay.match(line).hasMatch()) { - QStringList displays = line.split('"'); - relevantTextFromTest.display = displays[1]; - } else if (lineAssertCPU.match(line).hasMatch()) { - QStringList cpus = line.split('"'); - relevantTextFromTest.cpu = cpus[1]; - } else if (lineAssertGPU.match(line).hasMatch()) { - QStringList gpus = line.split('"'); - relevantTextFromTest.gpu = gpus[1]; } else if (lineStepSnapshot.match(line).hasMatch()) { QStringList tokens = line.split('"'); QString nameOfStep = tokens[1]; @@ -628,50 +596,6 @@ void Test::createMDFile(QString testDirectory) { stream << "## Preconditions" << "\n"; stream << "- In an empty region of a domain with editing rights." << "\n\n"; - // Platform - QStringList platforms = testScriptLines.platform.split(" ");; - stream << "## Platforms\n"; - stream << "Run the test on each of the following platforms\n"; - for (int i = 0; i < platforms.size(); ++i) { - // Note that the platforms parameter may include extra spaces, these appear as empty strings in the list - if (platforms[i] != QString()) { - stream << " - " << platforms[i] << "\n"; - } - } - - // Display - QStringList displays = testScriptLines.display.split(" "); - stream << "## Displays\n"; - stream << "Run the test on each of the following displays\n"; - for (int i = 0; i < displays.size(); ++i) { - // Note that the displays parameter may include extra spaces, these appear as empty strings in the list - if (displays[i] != QString()) { - stream << " - " << displays[i] << "\n"; - } - } - - // CPU - QStringList cpus = testScriptLines.cpu.split(" "); - stream << "## Processors\n"; - stream << "Run the test on each of the following processors\n"; - for (int i = 0; i < cpus.size(); ++i) { - // Note that the cpus parameter may include extra spaces, these appear as empty strings in the list - if (cpus[i] != QString()) { - stream << " - " << cpus[i] << "\n"; - } - } - - // GPU - QStringList gpus = testScriptLines.gpu.split(" "); - stream << "## Graphics Cards\n"; - stream << "Run the test on graphics cards from each of the following vendors\n"; - for (int i = 0; i < gpus.size(); ++i) { - // Note that the gpus parameter may include extra spaces, these appear as empty strings in the list - if (gpus[i] != QString()) { - stream << " - " << gpus[i] << "\n"; - } - } - stream << "## Steps\n"; stream << "Press space bar to advance step by step\n\n"; diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index e69459fef2..975d5dfdaf 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -30,10 +30,6 @@ using StepList = std::vector; class ExtractedText { public: QString title; - QString platform; - QString display; - QString cpu; - QString gpu; StepList stepList; }; From 0349847857fb2393c0894426b22011a60c2475a5 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 8 May 2018 17:46:25 -0700 Subject: [PATCH 088/152] Add comment re threading issues --- libraries/networking/src/HMACAuth.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/HMACAuth.h b/libraries/networking/src/HMACAuth.h index 59870bb7b6..1346bdee17 100644 --- a/libraries/networking/src/HMACAuth.h +++ b/libraries/networking/src/HMACAuth.h @@ -30,8 +30,12 @@ public: bool setKey(const QUuid& uidKey); // Calculate complete hash in one. bool calculateHash(HMACHash& hashResult, const char* data, int dataLen); - // Append data to be hashed. + + // Append to data to be hashed. bool addData(const char* data, int dataLen); + // Get the resulting hash from calls to addData(). + // Note that only one hash may be calculated at a time for each + // HMACAuth instance if this interface is used. HMACHash result(); private: From b0fee3fd8b09adff7a8eb78e566d7a656f201f85 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Wed, 9 May 2018 11:06:32 -0300 Subject: [PATCH 089/152] Improve code based on changes requested in the PR --- android/app/src/main/cpp/native.cpp | 17 +++++++---------- .../hifiinterface/view/DomainAdapter.java | 10 ++++++---- interface/src/AndroidHelper.cpp | 7 ------- interface/src/AndroidHelper.h | 6 ------ 4 files changed, 13 insertions(+), 27 deletions(-) diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp index 62ce9aec30..de2f6ec3e0 100644 --- a/android/app/src/main/cpp/native.cpp +++ b/android/app/src/main/cpp/native.cpp @@ -218,20 +218,17 @@ Java_io_highfidelity_hifiinterface_LoginActivity_nativeLogin(JNIEnv *env, jobjec env->ReleaseStringUTFChars(username_, c_username); env->ReleaseStringUTFChars(password_, c_password); - QSharedPointer accountManager = AndroidHelper::instance().getAccountManager(); + auto accountManager = DependencyManager::get(); __loginActivity = QAndroidJniObject(instance); QObject::connect(accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) { - AndroidHelper::instance().notifyLoginComplete(true); + jboolean jSuccess = (jboolean) true; + __loginActivity.callMethod("handleLoginCompleted", "(Z)V", jSuccess); }); QObject::connect(accountManager.data(), &AccountManager::loginFailed, []() { - AndroidHelper::instance().notifyLoginComplete(false); - }); - - QObject::connect(&AndroidHelper::instance(), &AndroidHelper::loginComplete, [](bool success) { - jboolean jSuccess = (jboolean) success; + jboolean jSuccess = (jboolean) false; __loginActivity.callMethod("handleLoginCompleted", "(Z)V", jSuccess); }); @@ -256,18 +253,18 @@ Java_io_highfidelity_hifiinterface_SplashActivity_registerLoadCompleteListener(J } JNIEXPORT jboolean JNICALL Java_io_highfidelity_hifiinterface_HomeActivity_nativeIsLoggedIn(JNIEnv *env, jobject instance) { - return AndroidHelper::instance().getAccountManager()->isLoggedIn(); + return DependencyManager::get()->isLoggedIn(); } JNIEXPORT void JNICALL Java_io_highfidelity_hifiinterface_HomeActivity_nativeLogout(JNIEnv *env, jobject instance) { - AndroidHelper::instance().getAccountManager()->logout(); + DependencyManager::get()->logout(); } JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_HomeActivity_nativeGetDisplayName(JNIEnv *env, jobject instance) { - QString username = AndroidHelper::instance().getAccountManager()->getAccountInfo().getUsername(); + QString username = DependencyManager::get()->getAccountInfo().getUsername(); return env->NewStringUTF(username.toLatin1().data()); } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java index 4f6394636f..461b71eb7c 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java @@ -60,10 +60,12 @@ public class DomainAdapter extends RecyclerView.Adapter AndroidHelper::getAccountManager() { - return DependencyManager::get(); -} - void AndroidHelper::requestActivity(const QString &activityName) { emit androidActivityRequested(activityName); } @@ -33,6 +29,3 @@ void AndroidHelper::goBackFromAndroidActivity() { emit backFromAndroidActivity(); } -void AndroidHelper::notifyLoginComplete(bool success) { - emit loginComplete(success); -} diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h index b9f7407453..51d8723db9 100644 --- a/interface/src/AndroidHelper.h +++ b/interface/src/AndroidHelper.h @@ -27,10 +27,6 @@ public: void notifyLoadComplete(); void goBackFromAndroidActivity(); - void notifyLoginComplete(bool success); - - QSharedPointer getAccountManager(); - AndroidHelper(AndroidHelper const&) = delete; void operator=(AndroidHelper const&) = delete; signals: @@ -38,8 +34,6 @@ signals: void backFromAndroidActivity(); void qtAppLoadComplete(); - void loginComplete(bool success); - private: AndroidHelper(); ~AndroidHelper(); From 1cc0a52597ca189f31d28cf31ce7fa3f32b1b9bd Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Wed, 9 May 2018 11:20:47 -0300 Subject: [PATCH 090/152] Fix the joystick texture corruption --- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 117 ++++++++++-------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 59cd637ca0..7c27fab591 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -28,69 +28,76 @@ void Basic2DWindowOpenGLDisplayPlugin::customizeContext() { qreal dpi = getFullscreenTarget()->physicalDotsPerInch(); _virtualPadPixelSize = dpi * VirtualPad::Manager::BASE_DIAMETER_PIXELS / VirtualPad::Manager::DPI; - auto iconPath = PathUtils::resourcesPath() + "images/analog_stick.png"; - auto image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); + if (!_virtualPadStickTexture) { + auto iconPath = PathUtils::resourcesPath() + "images/analog_stick.png"; + auto image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); - _virtualPadStickTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadStickTexture->setSource("virtualPad stick"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadStickTexture->setUsage(usage.build()); - _virtualPadStickTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadStickTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadStickTexture->setAutoGenerateMips(true); + _virtualPadStickTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadStickTexture->setSource("virtualPad stick"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadStickTexture->setUsage(usage.build()); + _virtualPadStickTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadStickTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadStickTexture->setAutoGenerateMips(true); + } } - iconPath = PathUtils::resourcesPath() + "images/analog_stick_base.png"; - image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); + if (!_virtualPadStickBaseTexture) { + auto iconPath = PathUtils::resourcesPath() + "images/analog_stick_base.png"; + auto image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); - _virtualPadStickBaseTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadStickBaseTexture->setSource("virtualPad base"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadStickBaseTexture->setUsage(usage.build()); - _virtualPadStickBaseTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadStickBaseTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadStickBaseTexture->setAutoGenerateMips(true); + _virtualPadStickBaseTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadStickBaseTexture->setSource("virtualPad base"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadStickBaseTexture->setUsage(usage.build()); + _virtualPadStickBaseTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadStickBaseTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadStickBaseTexture->setAutoGenerateMips(true); + } } + _virtualPadJumpBtnPixelSize = dpi * VirtualPad::Manager::JUMP_BTN_FULL_PIXELS / VirtualPad::Manager::DPI; - iconPath = PathUtils::resourcesPath() + "images/fly.png"; - image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadJumpBtnPixelSize, _virtualPadJumpBtnPixelSize, Qt::KeepAspectRatio); - image = image.mirrored(); + if (!_virtualPadJumpBtnTexture) { + auto iconPath = PathUtils::resourcesPath() + "images/fly.png"; + auto image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadJumpBtnPixelSize, _virtualPadJumpBtnPixelSize, Qt::KeepAspectRatio); + image = image.mirrored(); - _virtualPadJumpBtnTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadJumpBtnTexture->setSource("virtualPad jump"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadJumpBtnTexture->setUsage(usage.build()); - _virtualPadJumpBtnTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadJumpBtnTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadJumpBtnTexture->setAutoGenerateMips(true); + _virtualPadJumpBtnTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadJumpBtnTexture->setSource("virtualPad jump"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadJumpBtnTexture->setUsage(usage.build()); + _virtualPadJumpBtnTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadJumpBtnTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadJumpBtnTexture->setAutoGenerateMips(true); + } } #endif Parent::customizeContext(); From 06c6f5506904f964b8c77e99ca7b083e5546c468 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 9 May 2018 09:35:42 -0700 Subject: [PATCH 091/152] MS14951: Fix Snapshot hotkey sound playback --- 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 038180a60d..525f0f2ee7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2128,7 +2128,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return entityServerNode && !isPhysicsEnabled(); }); - _snapshotSound = DependencyManager::get()->getSound(PathUtils::resourcesUrl("sounds/snap.wav")); + _snapshotSound = DependencyManager::get()->getSound(PathUtils::resourcesUrl("sounds/snapshot/snap.wav")); QVariant testProperty = property(hifi::properties::TEST); qDebug() << testProperty; From 542e707de8d6d1cacb0e6b3e05f4b5258bff9921 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 9 May 2018 09:35:42 -0700 Subject: [PATCH 092/152] MS14951: Fix Snapshot hotkey sound playback --- 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 789f60bdb1..6a063fb990 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2093,7 +2093,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return entityServerNode && !isPhysicsEnabled(); }); - _snapshotSound = DependencyManager::get()->getSound(PathUtils::resourcesUrl("sounds/snap.wav")); + _snapshotSound = DependencyManager::get()->getSound(PathUtils::resourcesUrl("sounds/snapshot/snap.wav")); QVariant testProperty = property(hifi::properties::TEST); qDebug() << testProperty; From 843282739e937e3df5ced9f3b58e558d7e452580 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Wed, 9 May 2018 14:16:51 -0300 Subject: [PATCH 093/152] Remove unused includes and white spaces --- interface/src/AndroidHelper.h | 2 -- interface/src/Application.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h index 51d8723db9..019db9c4a7 100644 --- a/interface/src/AndroidHelper.h +++ b/interface/src/AndroidHelper.h @@ -13,8 +13,6 @@ #define hifi_Android_Helper_h #include -#include -#include class AndroidHelper : public QObject { Q_OBJECT diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e82a6d9965..565400faac 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4330,7 +4330,7 @@ void setupCpuMonitorThread() { void Application::idle() { PerformanceTimer perfTimer("idle"); - + // Update the deadlock watchdog updateHeartbeat(); From db03265a6b8e0f2fa4873929fc5ec3c932e71d71 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 8 May 2018 18:49:55 -0700 Subject: [PATCH 094/152] when in serverless mode, short-circuit simulation ownership bids --- .../entities/src/EntityEditPacketSender.cpp | 8 -------- libraries/octree/src/OctreeEditPacketSender.cpp | 9 --------- libraries/octree/src/OctreeEditPacketSender.h | 3 --- libraries/physics/src/EntityMotionState.cpp | 8 +++++++- libraries/physics/src/EntityMotionState.h | 2 ++ .../physics/src/PhysicalEntitySimulation.cpp | 16 ++++++++++++---- 6 files changed, 21 insertions(+), 25 deletions(-) diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index 5d7bd61854..c0a45936ac 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -73,7 +73,6 @@ void EntityEditPacketSender::queueEditAvatarEntityMessage(PacketType type, _myAvatar->updateAvatarEntity(entityItemID, binaryProperties); entity->setLastBroadcast(usecTimestampNow()); - return; } @@ -81,10 +80,6 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, EntityTreePointer entityTree, EntityItemID entityItemID, const EntityItemProperties& properties) { - if (!_shouldSend) { - return; // bail early - } - if (properties.getClientOnly() && properties.getOwningAvatarID() == _myAvatar->getID()) { // this is an avatar-based entity --> update our avatar-data rather than sending to the entity-server queueEditAvatarEntityMessage(type, entityTree, entityItemID, properties); @@ -143,9 +138,6 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, } void EntityEditPacketSender::queueEraseEntityMessage(const EntityItemID& entityItemID) { - if (!_shouldSend) { - return; // bail early - } // in case this was a clientOnly entity: if(_myAvatar) { diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index 4f10c9bf79..4bc20c80c6 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -22,7 +22,6 @@ const int OctreeEditPacketSender::DEFAULT_MAX_PENDING_MESSAGES = PacketSender::D OctreeEditPacketSender::OctreeEditPacketSender() : - _shouldSend(true), _maxPendingMessages(DEFAULT_MAX_PENDING_MESSAGES), _releaseQueuedMessagesPending(false) { @@ -145,10 +144,6 @@ void OctreeEditPacketSender::queuePendingPacketToNodes(std::unique_ptr } void OctreeEditPacketSender::queuePacketToNodes(std::unique_ptr packet) { - if (!_shouldSend) { - return; // bail early - } - assert(serversExist()); // we must have servers to be here!! auto node = DependencyManager::get()->soloNodeOfType(getMyNodeType()); @@ -161,10 +156,6 @@ void OctreeEditPacketSender::queuePacketToNodes(std::unique_ptr packet // NOTE: editMessage - is JUST the octcode/color and does not contain the packet header void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, QByteArray& editMessage) { - if (!_shouldSend) { - return; // bail early - } - // If we don't have servers, then we will simply queue up all of these packets and wait till we have // servers for processing if (!serversExist()) { diff --git a/libraries/octree/src/OctreeEditPacketSender.h b/libraries/octree/src/OctreeEditPacketSender.h index 8a33eb8b73..1dad5b74c7 100644 --- a/libraries/octree/src/OctreeEditPacketSender.h +++ b/libraries/octree/src/OctreeEditPacketSender.h @@ -41,12 +41,10 @@ public: /// are we in sending mode. If we're not in sending mode then all packets and messages will be ignored and /// not queued and not sent - bool getShouldSend() const { return _shouldSend; } /// set sending mode. By default we are set to shouldSend=TRUE and packets will be sent. If shouldSend=FALSE, then we'll /// switch to not sending mode, and all packets and messages will be ignored, not queued, and not sent. This might be used /// in an application like interface when all octree features are disabled. - void setShouldSend(bool shouldSend) { _shouldSend = shouldSend; } /// if you're running in non-threaded mode, you must call this method regularly virtual bool process() override; @@ -76,7 +74,6 @@ public slots: protected: using EditMessagePair = std::pair; - bool _shouldSend; void queuePacketToNode(const QUuid& nodeID, std::unique_ptr packet); void queuePacketListToNode(const QUuid& nodeUUID, std::unique_ptr packetList); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index c2bacd4949..47297adef5 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -348,7 +348,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { if (_numInactiveUpdates > 0) { const uint8_t MAX_NUM_INACTIVE_UPDATES = 20; - if (_numInactiveUpdates > MAX_NUM_INACTIVE_UPDATES) { + if (_numInactiveUpdates > MAX_NUM_INACTIVE_UPDATES || isServerlessMode()) { // clear local ownership (stop sending updates) and let the server clear itself _entity->clearSimulationOwnership(); return false; @@ -827,3 +827,9 @@ void EntityMotionState::clearObjectVelocities() const { } _entity->setAcceleration(glm::vec3(0.0f)); } + +bool EntityMotionState::isServerlessMode() { + EntityTreeElementPointer element = _entity->getElement(); + EntityTreePointer tree = element ? element->getTree() : nullptr; + return tree ? tree->isServerlessMode() : false; +} diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index a542c61d43..376cc5afe2 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -156,6 +156,8 @@ protected: uint8_t _numInactiveUpdates { 1 }; uint8_t _bidPriority { 0 }; bool _serverVariablesSet { false }; + + bool isServerlessMode(); }; #endif // hifi_EntityMotionState_h diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index ab7c2ec252..467de22591 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -327,10 +327,18 @@ void PhysicalEntitySimulation::handleChangedMotionStates(const VectorOfMotionSta } void PhysicalEntitySimulation::addOwnershipBid(EntityMotionState* motionState) { - motionState->initForBid(); - motionState->sendBid(_entityPacketSender, _physicsEngine->getNumSubsteps()); - _bids.push_back(motionState); - _nextBidExpiry = glm::min(_nextBidExpiry, motionState->getNextBidExpiry()); + if (getEntityTree()->isServerlessMode()) { + EntityItemPointer entity = motionState->getEntity(); + auto nodeList = DependencyManager::get(); + auto sessionID = nodeList->getSessionUUID(); + entity->setSimulationOwner(SimulationOwner(sessionID, SCRIPT_GRAB_SIMULATION_PRIORITY)); + _owned.push_back(motionState); + } else { + motionState->initForBid(); + motionState->sendBid(_entityPacketSender, _physicsEngine->getNumSubsteps()); + _bids.push_back(motionState); + _nextBidExpiry = glm::min(_nextBidExpiry, motionState->getNextBidExpiry()); + } } void PhysicalEntitySimulation::addOwnership(EntityMotionState* motionState) { From 32f2494416a64a210a2da668be9a87485018e029 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Wed, 9 May 2018 11:58:16 -0700 Subject: [PATCH 095/152] Stores previous user-selected folders. --- tools/auto-tester/src/Test.cpp | 128 +++++++++++++++++++++++---------- tools/auto-tester/src/Test.h | 7 +- 2 files changed, 96 insertions(+), 39 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index bdf734897e..1ab934cf63 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -176,33 +176,38 @@ void Test::appendTestResultsToFile(QString testResultsFolderPath, TestFailure te void Test::startTestsEvaluation() { // Get list of JPEG images in folder, sorted by name - pathToTestResultsDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", ".", QFileDialog::ShowDirsOnly); - if (pathToTestResultsDirectory == "") { + QString previousSelection = snapshotDirectory; + + snapshotDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", + previousSelection, QFileDialog::ShowDirsOnly); + + // If user cancelled then restore previous selection and return + if (snapshotDirectory == "") { + snapshotDirectory = previousSelection; return; } // Quit if test results folder could not be created - if (!createTestResultsFolderPath(pathToTestResultsDirectory)) { + if (!createTestResultsFolderPath(snapshotDirectory)) { return; } // Before any processing - all images are converted to PNGs, as this is the format stored on GitHub - QStringList sortedSnapshotFilenames = createListOfAll_imagesInDirectory("jpg", pathToTestResultsDirectory); + QStringList sortedSnapshotFilenames = createListOfAll_imagesInDirectory("jpg", snapshotDirectory); foreach(QString filename, sortedSnapshotFilenames) { QStringList stringParts = filename.split("."); - copyJPGtoPNG( - pathToTestResultsDirectory + "/" + stringParts[0] + ".jpg", - pathToTestResultsDirectory + "/" + stringParts[0] + ".png" + copyJPGtoPNG(snapshotDirectory + "/" + stringParts[0] + ".jpg", + snapshotDirectory + "/" + stringParts[0] + ".png" ); - QFile::remove(pathToTestResultsDirectory + "/" + stringParts[0] + ".jpg"); + QFile::remove(snapshotDirectory + "/" + stringParts[0] + ".jpg"); } // Create two lists. The first is the test results, the second is the expected images // The expected images are represented as a URL to enable download from GitHub // Images that are in the wrong format are ignored. - QStringList sortedTestResultsFilenames = createListOfAll_imagesInDirectory("png", pathToTestResultsDirectory); + QStringList sortedTestResultsFilenames = createListOfAll_imagesInDirectory("png", snapshotDirectory); QStringList expectedImagesURLs; resultImagesFullFilenames.clear(); @@ -210,7 +215,7 @@ void Test::startTestsEvaluation() { expectedImagesFullFilenames.clear(); foreach(QString currentFilename, sortedTestResultsFilenames) { - QString fullCurrentFilename = pathToTestResultsDirectory + "/" + currentFilename; + QString fullCurrentFilename = snapshotDirectory + "/" + currentFilename; if (isInSnapshotFilenameFormat("png", currentFilename)) { resultImagesFullFilenames << fullCurrentFilename; @@ -230,11 +235,11 @@ void Test::startTestsEvaluation() { QString expectedImageFilename = currentFilename.replace("/", "_").replace(".", "_EI."); expectedImagesFilenames << expectedImageFilename; - expectedImagesFullFilenames << pathToTestResultsDirectory + "/" + expectedImageFilename; + expectedImagesFullFilenames << snapshotDirectory + "/" + expectedImageFilename; } } - autoTester->downloadImages(expectedImagesURLs, pathToTestResultsDirectory, expectedImagesFilenames); + autoTester->downloadImages(expectedImagesURLs, snapshotDirectory, expectedImagesFilenames); } void Test::finishTestsEvaluation(bool interactiveMode, QProgressBar* progressBar) { @@ -295,25 +300,39 @@ void Test::importTest(QTextStream& textStream, const QString& testPathname) { // This script will run all text.js scripts in every applicable sub-folder void Test::createRecursiveScript() { // Select folder to start recursing from - QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder that will contain the top level test script", ".", QFileDialog::ShowDirsOnly); - if (topLevelDirectory == "") { + QString previousSelection = testDirectory; + + testDirectory = + QFileDialog::getExistingDirectory(nullptr, "Please select folder that will contain the top level test script", + previousSelection, QFileDialog::ShowDirsOnly); + + // If user cancelled then restore previous selection and return + if (testDirectory == "") { + testDirectory = previousSelection; return; } - createRecursiveScript(topLevelDirectory, true); + createRecursiveScript(testDirectory, true); } // This method creates a `testRecursive.js` script in every sub-folder. void Test::createAllRecursiveScripts() { // Select folder to start recursing from - QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the recursive scripts", ".", QFileDialog::ShowDirsOnly); - if (topLevelDirectory == "") { + QString previousSelection = testDirectory; + + testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the recursive scripts", + previousSelection, + QFileDialog::ShowDirsOnly); + + // If user cancelled then restore previous selection and return + if (testDirectory == "") { + testDirectory = previousSelection; return; } - createRecursiveScript(topLevelDirectory, false); + createRecursiveScript(testDirectory, false); - QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories); + QDirIterator it(testDirectory.toStdString().c_str(), QDirIterator::Subdirectories); while (it.hasNext()) { QString directory = it.next(); @@ -416,29 +435,42 @@ void Test::createRecursiveScript(QString topLevelDirectory, bool interactiveMode void Test::createTest() { // Rename files sequentially, as ExpectedResult_00000.jpeg, ExpectedResult_00001.jpg and so on // Any existing expected result images will be deleted - QString imageSourceDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", ".", QFileDialog::ShowDirsOnly); - if (imageSourceDirectory == "") { + QString previousSelection = snapshotDirectory; + + snapshotDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", + previousSelection, + QFileDialog::ShowDirsOnly); + + // If user cancelled then restore previous selection and return + if (snapshotDirectory == "") { + snapshotDirectory = previousSelection; return; } - QString imageDestinationDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder to save the test images", ".", QFileDialog::ShowDirsOnly); - if (imageDestinationDirectory == "") { + previousSelection = testDirectory; + + QString testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder to save the test images", + previousSelection, QFileDialog::ShowDirsOnly); + + // If user cancelled then restore previous selection and return + if (testDirectory == "") { + testDirectory = previousSelection; return; } - QStringList sortedImageFilenames = createListOfAll_imagesInDirectory("jpg", imageSourceDirectory); + QStringList sortedImageFilenames = createListOfAll_imagesInDirectory("jpg", snapshotDirectory); int i = 1; const int maxImages = pow(10, NUM_DIGITS); foreach (QString currentFilename, sortedImageFilenames) { - QString fullCurrentFilename = imageSourceDirectory + "/" + currentFilename; + QString fullCurrentFilename = snapshotDirectory + "/" + currentFilename; if (isInSnapshotFilenameFormat("jpg", currentFilename)) { if (i >= maxImages) { messageBox.critical(0, "Error", "More than " + QString::number(maxImages) + " images not supported"); exit(-1); } QString newFilename = "ExpectedImage_" + QString::number(i - 1).rightJustified(5, '0') + ".png"; - QString fullNewFileName = imageDestinationDirectory + "/" + newFilename; + QString fullNewFileName = testDirectory + "/" + newFilename; try { copyJPGtoPNG(fullCurrentFilename, fullNewFileName); @@ -486,7 +518,7 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { const QRegularExpression lineStepSnapshot = QRegularExpression(regexStepSnapshot); const QString functionAddStepName(ws + "autoTester" + ws + "\\." + ws + "addStep"); - const QString regexStep(ws + functionAddStepName + ws + "\\(" + ws + quotedString + ws + "\\)" + ".*"); + const QString regexStep(ws + functionAddStepName + ws + "\\(" + ws + quotedString + ".*"); const QRegularExpression lineStep = QRegularExpression(regexStep); while (!line.isNull()) { @@ -522,29 +554,43 @@ ExtractedText Test::getTestScriptLines(QString testFileName) { // The folder selected must contain a script named "test.js", the file produced is named "test.md" void Test::createMDFile() { // Folder selection - QString testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test", ".", QFileDialog::ShowDirsOnly); + QString previousSelection = testDirectory; + + testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test", previousSelection, + QFileDialog::ShowDirsOnly); + + // If user cancelled then restore previous selection and return if (testDirectory == "") { + testDirectory = previousSelection; return; } createMDFile(testDirectory); + + messageBox.information(0, "Success", "MD file has been created"); } void Test::createAllMDFiles() { // Select folder to start recursing from - QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the MD files", ".", QFileDialog::ShowDirsOnly); - if (topLevelDirectory == "") { + QString previousSelection = testDirectory; + + testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the MD files", + previousSelection, QFileDialog::ShowDirsOnly); + + // If user cancelled then restore previous selection and return + if (testDirectory == "") { + testDirectory = previousSelection; return; } // First test if top-level folder has a test.js file - const QString testPathname{ topLevelDirectory + "/" + TEST_FILENAME }; + const QString testPathname { testDirectory + "/" + TEST_FILENAME }; QFileInfo fileInfo(testPathname); if (fileInfo.exists()) { - createMDFile(topLevelDirectory); + createMDFile(testDirectory); } - QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories); + QDirIterator it(testDirectory.toStdString().c_str(), QDirIterator::Subdirectories); while (it.hasNext()) { QString directory = it.next(); @@ -613,13 +659,19 @@ void Test::createMDFile(QString testDirectory) { } void Test::createTestsOutline() { - QString testsRootDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the tests root folder", ".", QFileDialog::ShowDirsOnly); - if (testsRootDirectory == "") { + QString previousSelection = testDirectory; + + testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the tests root folder", previousSelection, + QFileDialog::ShowDirsOnly); + + // If user cancelled then restore previous selection and return + if (testDirectory == "") { + testDirectory = previousSelection; return; } const QString testsOutlineFilename { "testsOutline.md" }; - QString mdFilename(testsRootDirectory + "/" + testsOutlineFilename); + QString mdFilename(testDirectory + "/" + testsOutlineFilename); QFile mdFile(mdFilename); if (!mdFile.open(QIODevice::WriteOnly)) { messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + mdFilename); @@ -633,10 +685,10 @@ void Test::createTestsOutline() { stream << "Directories with an appended (*) have an automatic test\n\n"; // We need to know our current depth, as this isn't given by QDirIterator - int rootDepth { testsRootDirectory.count('/') }; + int rootDepth { testDirectory.count('/') }; // Each test is shown as the folder name linking to the matching GitHub URL, and the path to the associated test.md file - QDirIterator it(testsRootDirectory.toStdString().c_str(), QDirIterator::Subdirectories); + QDirIterator it(testDirectory.toStdString().c_str(), QDirIterator::Subdirectories); while (it.hasNext()) { QString directory = it.next(); diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index 975d5dfdaf..896fe24fcc 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -91,7 +91,12 @@ private: const int NUM_DIGITS { 5 }; const QString EXPECTED_IMAGE_PREFIX { "ExpectedImage_" }; - QString pathToTestResultsDirectory; + // We have to directories to work with. + // The first is the directory containing the test we are working with + // The second contains the snapshots taken for test runs that need to be evaluated + QString testDirectory; + QString snapshotDirectory; + QStringList expectedImagesFilenames; QStringList expectedImagesFullFilenames; QStringList resultImagesFullFilenames; From f454dac709d5b709545a7e484f7c3eed30333594 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 May 2018 12:04:44 -0700 Subject: [PATCH 096/152] avoid div by zero when measuring acceleration --- libraries/physics/src/EntityMotionState.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index a801392b66..fbb4b69ce0 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -731,7 +731,9 @@ void EntityMotionState::measureBodyAcceleration() { // hence the equation for acceleration is: a = (v1 / (1 - D)^dt - v0) / dt glm::vec3 velocity = getBodyLinearVelocityGTSigma(); - _measuredAcceleration = (velocity / powf(1.0f - _body->getLinearDamping(), dt) - _lastVelocity) * invDt; + const float MIN_DAMPING_FACTOR = 0.01f; + float dampingAttenuationFactor = 1.0f / glm::max(powf(1.0f - _body->getLinearDamping(), dt), MIN_DAMPING_FACTOR); + _measuredAcceleration = (velocity * dampingAttenuationFactor - _lastVelocity) * invDt; _lastVelocity = velocity; if (numSubsteps > PHYSICS_ENGINE_MAX_NUM_SUBSTEPS) { // we fall in here when _lastMeasureStep is old: the body has just become active From b8d34f4b8fee9f754f7312f6351bc347db31ba85 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 May 2018 12:13:27 -0700 Subject: [PATCH 097/152] more correct variable name --- libraries/physics/src/EntityMotionState.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index fbb4b69ce0..e04055ec32 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -732,8 +732,8 @@ void EntityMotionState::measureBodyAcceleration() { glm::vec3 velocity = getBodyLinearVelocityGTSigma(); const float MIN_DAMPING_FACTOR = 0.01f; - float dampingAttenuationFactor = 1.0f / glm::max(powf(1.0f - _body->getLinearDamping(), dt), MIN_DAMPING_FACTOR); - _measuredAcceleration = (velocity * dampingAttenuationFactor - _lastVelocity) * invDt; + float invDampingAttenuationFactor = 1.0f / glm::max(powf(1.0f - _body->getLinearDamping(), dt), MIN_DAMPING_FACTOR); + _measuredAcceleration = (velocity * invDampingAttenuationFactor - _lastVelocity) * invDt; _lastVelocity = velocity; if (numSubsteps > PHYSICS_ENGINE_MAX_NUM_SUBSTEPS) { // we fall in here when _lastMeasureStep is old: the body has just become active From 7466d08f1f3c3d5ee500d4a499839c88469667a9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 5 May 2018 16:42:44 -0700 Subject: [PATCH 098/152] more suppression of logging --- interface/src/Application.cpp | 43 +++++++++++++++++-- libraries/entities/src/EntityItem.cpp | 2 +- libraries/qml/src/qml/Logging.h | 4 +- libraries/script-engine/src/ScriptEngine.cpp | 6 +-- .../script-engine/src/ScriptEngineLogging.cpp | 1 + .../script-engine/src/ScriptEngineLogging.h | 1 + 6 files changed, 47 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ec28dcb3dd..c9055e92b2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -154,6 +154,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include "AudioClient.h" #include "audio/AudioScope.h" @@ -1372,8 +1379,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // Needs to happen AFTER the render engine initialization to access its configuration initializeUi(); - updateVerboseLogging(); - init(); qCDebug(interfaceapp, "init() complete."); @@ -1713,6 +1718,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo loadSettings(); + updateVerboseLogging(); + // Now that we've loaded the menu and thus switched to the previous display plugin // we can unlock the desktop repositioning code, since all the positions will be // relative to the desktop size for this plugin @@ -2254,10 +2261,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _pendingRenderEvent = false; qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); + + updateVerboseLogging(); } void Application::updateVerboseLogging() { - bool enable = Menu::getInstance()->isOptionChecked(MenuOption::VerboseLogging); + auto menu = Menu::getInstance(); + if (!menu) { + return; + } + bool enable = menu->isOptionChecked(MenuOption::VerboseLogging); const_cast(&animation())->setEnabled(QtDebugMsg, enable); const_cast(&animation())->setEnabled(QtInfoMsg, enable); @@ -2268,6 +2281,12 @@ void Application::updateVerboseLogging() { const_cast(&scriptengine())->setEnabled(QtDebugMsg, enable); const_cast(&scriptengine())->setEnabled(QtInfoMsg, enable); + const_cast(&scriptengine_module())->setEnabled(QtDebugMsg, enable); + const_cast(&scriptengine_module())->setEnabled(QtInfoMsg, enable); + + const_cast(&scriptengine_script())->setEnabled(QtDebugMsg, enable); + const_cast(&scriptengine_script())->setEnabled(QtInfoMsg, enable); + const_cast(&modelformat())->setEnabled(QtDebugMsg, enable); const_cast(&modelformat())->setEnabled(QtInfoMsg, enable); @@ -2294,6 +2313,24 @@ void Application::updateVerboseLogging() { const_cast(&glLogging())->setEnabled(QtDebugMsg, enable); const_cast(&glLogging())->setEnabled(QtInfoMsg, enable); + + const_cast(&shared())->setEnabled(QtDebugMsg, enable); + const_cast(&shared())->setEnabled(QtInfoMsg, enable); + + const_cast(&plugins())->setEnabled(QtDebugMsg, enable); + const_cast(&plugins())->setEnabled(QtInfoMsg, enable); + + const_cast(&gpulogging())->setEnabled(QtDebugMsg, enable); + const_cast(&gpulogging())->setEnabled(QtInfoMsg, enable); + + const_cast(&gpugllogging())->setEnabled(QtDebugMsg, enable); + const_cast(&gpugllogging())->setEnabled(QtInfoMsg, enable); + + const_cast(&qmlLogging())->setEnabled(QtDebugMsg, enable); + const_cast(&qmlLogging())->setEnabled(QtInfoMsg, enable); + + const_cast(&entities())->setEnabled(QtDebugMsg, enable); + const_cast(&entities())->setEnabled(QtInfoMsg, enable); } void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) { diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 1d81a6ae6d..d35c01a51b 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1070,7 +1070,7 @@ bool EntityItem::stepKinematicMotion(float timeElapsed) { const float MAX_TIME_ELAPSED = 1.0f; // seconds if (timeElapsed > MAX_TIME_ELAPSED) { - qCWarning(entities) << "kinematic timestep = " << timeElapsed << " truncated to " << MAX_TIME_ELAPSED; + qCDebug(entities) << "kinematic timestep = " << timeElapsed << " truncated to " << MAX_TIME_ELAPSED; } timeElapsed = glm::min(timeElapsed, MAX_TIME_ELAPSED); diff --git a/libraries/qml/src/qml/Logging.h b/libraries/qml/src/qml/Logging.h index 487566701d..48efdd1da9 100644 --- a/libraries/qml/src/qml/Logging.h +++ b/libraries/qml/src/qml/Logging.h @@ -6,8 +6,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_Controllers_Logging_h -#define hifi_Controllers_Logging_h +#ifndef hifi_QML_Logging_h +#define hifi_QML_Logging_h #include diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 9a383454d4..23ffbabe77 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -101,8 +101,6 @@ int functionSignatureMetaID = qRegisterMetaType(); -Q_LOGGING_CATEGORY(scriptengineScript, "hifi.scriptengine.script") - static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) { QString message = ""; for (int i = 0; i < context->argumentCount(); i++) { @@ -115,9 +113,9 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) { if (ScriptEngine *scriptEngine = qobject_cast(engine)) { scriptEngine->print(message); // prefix the script engine name to help disambiguate messages in the main debug log - qCDebug(scriptengineScript, "[%s] %s", qUtf8Printable(scriptEngine->getFilename()), qUtf8Printable(message)); + qCDebug(scriptengine_script, "[%s] %s", qUtf8Printable(scriptEngine->getFilename()), qUtf8Printable(message)); } else { - qCDebug(scriptengineScript, "%s", qUtf8Printable(message)); + qCDebug(scriptengine_script, "%s", qUtf8Printable(message)); } return QScriptValue(); diff --git a/libraries/script-engine/src/ScriptEngineLogging.cpp b/libraries/script-engine/src/ScriptEngineLogging.cpp index 392bc05129..b51d7c3780 100644 --- a/libraries/script-engine/src/ScriptEngineLogging.cpp +++ b/libraries/script-engine/src/ScriptEngineLogging.cpp @@ -13,3 +13,4 @@ Q_LOGGING_CATEGORY(scriptengine, "hifi.scriptengine") Q_LOGGING_CATEGORY(scriptengine_module, "hifi.scriptengine.module") +Q_LOGGING_CATEGORY(scriptengine_script, "hifi.scriptengine.script") diff --git a/libraries/script-engine/src/ScriptEngineLogging.h b/libraries/script-engine/src/ScriptEngineLogging.h index 62e46632a6..3096dd4927 100644 --- a/libraries/script-engine/src/ScriptEngineLogging.h +++ b/libraries/script-engine/src/ScriptEngineLogging.h @@ -16,6 +16,7 @@ Q_DECLARE_LOGGING_CATEGORY(scriptengine) Q_DECLARE_LOGGING_CATEGORY(scriptengine_module) +Q_DECLARE_LOGGING_CATEGORY(scriptengine_script) #endif // hifi_ScriptEngineLogging_h From 16e832ac0894a2c2413dbdc3328da148757c00d0 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 9 May 2018 13:01:33 -0700 Subject: [PATCH 099/152] use setFilterRules rather than specifying each logging category to suppress --- interface/src/Application.cpp | 82 ++--------------------------------- 1 file changed, 4 insertions(+), 78 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c9055e92b2..20efe73f08 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -145,23 +145,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "AudioClient.h" #include "audio/AudioScope.h" #include "avatar/AvatarManager.h" @@ -2261,8 +2244,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _pendingRenderEvent = false; qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); - - updateVerboseLogging(); } void Application::updateVerboseLogging() { @@ -2272,65 +2253,10 @@ void Application::updateVerboseLogging() { } bool enable = menu->isOptionChecked(MenuOption::VerboseLogging); - const_cast(&animation())->setEnabled(QtDebugMsg, enable); - const_cast(&animation())->setEnabled(QtInfoMsg, enable); - - const_cast(&avatars())->setEnabled(QtDebugMsg, enable); - const_cast(&avatars())->setEnabled(QtInfoMsg, enable); - - const_cast(&scriptengine())->setEnabled(QtDebugMsg, enable); - const_cast(&scriptengine())->setEnabled(QtInfoMsg, enable); - - const_cast(&scriptengine_module())->setEnabled(QtDebugMsg, enable); - const_cast(&scriptengine_module())->setEnabled(QtInfoMsg, enable); - - const_cast(&scriptengine_script())->setEnabled(QtDebugMsg, enable); - const_cast(&scriptengine_script())->setEnabled(QtInfoMsg, enable); - - const_cast(&modelformat())->setEnabled(QtDebugMsg, enable); - const_cast(&modelformat())->setEnabled(QtInfoMsg, enable); - - const_cast(&controllers())->setEnabled(QtDebugMsg, enable); - const_cast(&controllers())->setEnabled(QtInfoMsg, enable); - - const_cast(&resourceLog())->setEnabled(QtDebugMsg, enable); - const_cast(&resourceLog())->setEnabled(QtInfoMsg, enable); - - const_cast(&networking())->setEnabled(QtDebugMsg, enable); - const_cast(&networking())->setEnabled(QtInfoMsg, enable); - - const_cast(&asset_client())->setEnabled(QtDebugMsg, enable); - const_cast(&asset_client())->setEnabled(QtInfoMsg, enable); - - const_cast(&messages_client())->setEnabled(QtDebugMsg, enable); - const_cast(&messages_client())->setEnabled(QtInfoMsg, enable); - - const_cast(&storagelogging())->setEnabled(QtDebugMsg, enable); - const_cast(&storagelogging())->setEnabled(QtInfoMsg, enable); - - const_cast(&uiLogging())->setEnabled(QtDebugMsg, enable); - const_cast(&uiLogging())->setEnabled(QtInfoMsg, enable); - - const_cast(&glLogging())->setEnabled(QtDebugMsg, enable); - const_cast(&glLogging())->setEnabled(QtInfoMsg, enable); - - const_cast(&shared())->setEnabled(QtDebugMsg, enable); - const_cast(&shared())->setEnabled(QtInfoMsg, enable); - - const_cast(&plugins())->setEnabled(QtDebugMsg, enable); - const_cast(&plugins())->setEnabled(QtInfoMsg, enable); - - const_cast(&gpulogging())->setEnabled(QtDebugMsg, enable); - const_cast(&gpulogging())->setEnabled(QtInfoMsg, enable); - - const_cast(&gpugllogging())->setEnabled(QtDebugMsg, enable); - const_cast(&gpugllogging())->setEnabled(QtInfoMsg, enable); - - const_cast(&qmlLogging())->setEnabled(QtDebugMsg, enable); - const_cast(&qmlLogging())->setEnabled(QtInfoMsg, enable); - - const_cast(&entities())->setEnabled(QtDebugMsg, enable); - const_cast(&entities())->setEnabled(QtInfoMsg, enable); + QString rules = "*.debug=%1\n" + "*.info=%1"; + rules = rules.arg(enable ? "true" : "false"); + QLoggingCategory::setFilterRules(rules); } void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) { From 936a319e620d0b32aaeea70e9a4bce34f11a858f Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Wed, 9 May 2018 17:15:57 -0300 Subject: [PATCH 100/152] Android - First version of showing up avatars names upon touch. Brought back (transparent) overlays into render forward task. --- .../render-utils/src/RenderForwardTask.cpp | 19 ++- scripts/system/+android/displayNames.js | 160 ++++++++++++++++++ scripts/system/+android/modes.js | 1 + 3 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 scripts/system/+android/displayNames.js diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 63370109e0..c45e1dd4eb 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -21,6 +21,9 @@ #include +#include + +#include "AntialiasingEffect.h" #include "StencilMaskPass.h" #include "ZoneRenderer.h" #include "FadeEffect.h" @@ -54,12 +57,15 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT]; const auto& metas = items.get0()[RenderFetchCullSortTask::META]; // const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE]; - // const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE]; + const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE]; + //const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND]; // const auto& spatialSelection = items[1]; fadeEffect->build(task, opaques); + const auto jitter = task.addJob("JitterCam"); + // Prepare objects shared by several jobs const auto deferredFrameTransform = task.addJob("DeferredFrameTransform"); const auto lightingModel = task.addJob("LightingModel"); @@ -75,6 +81,17 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // draw a stencil mask in hidden regions of the framebuffer. task.addJob("PrepareStencil", framebuffer); + // Layered Overlays + //const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT); + const auto filteredOverlaysTransparent = task.addJob("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT); + //const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN(0); + const auto overlaysInFrontTransparent = filteredOverlaysTransparent.getN(0); + + //const auto overlayInFrontOpaquesInputs = DrawOverlay3D::Inputs(overlaysInFrontOpaque, lightingModel, jitter).asVarying(); + const auto overlayInFrontTransparentsInputs = DrawOverlay3D::Inputs(overlaysInFrontTransparent, lightingModel, jitter).asVarying(); + //task.addJob("DrawOverlayInFrontOpaque", overlayInFrontOpaquesInputs, true); + task.addJob("DrawOverlayInFrontTransparent", overlayInFrontTransparentsInputs, false); + // Draw opaques forward const auto opaqueInputs = DrawForward::Inputs(opaques, lightingModel).asVarying(); task.addJob("DrawOpaques", opaqueInputs, shapePlumber); diff --git a/scripts/system/+android/displayNames.js b/scripts/system/+android/displayNames.js new file mode 100644 index 0000000000..8ed2b35daf --- /dev/null +++ b/scripts/system/+android/displayNames.js @@ -0,0 +1,160 @@ +"use strict"; +// +// displayNames.js +// scripts/system/ +// +// Created by Cristian Duarte & Gabriel Calero on May 3, 2018 +// 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 +// +(function() { // BEGIN LOCAL_SCOPE + +var MAX_DISTANCE_PX = 20; // Should we use dp instead? +var UNKNOWN_NAME = "Unknown"; +var METERS_ABOVE_HEAD = 0.4; + +var TEXT_LINE_HEIGHT = .1; +var TEXT_MARGIN = 0.025; + +var currentTouchToAnalize = null; +var rayExclusionList = []; + +var currentlyShownAvatar = { + avatarID: null, + avatar: null, + overlay: null +}; + +var logEnabled = false; + +function printd(str) { + if (logEnabled) { + print("[displayNames.js] " + str); + } +} + +function touchedAvatar(avatarID, avatarData) { + printd("[AVATARNAME] touchEnd FOUND " + JSON.stringify(avatarData)); + + // Case: touching an already selected avatar + if (currentlyShownAvatar.avatar && currentlyShownAvatar.avatarID == avatarID) { + currentlyShownAvatar.avatar = null; + if (currentlyShownAvatar.overlay) { + Overlays.editOverlay(currentlyShownAvatar.overlay, {visible: false}); + } + return; + } + + // Save currently selected avatar + currentlyShownAvatar.avatarID = avatarID; + currentlyShownAvatar.avatar = avatarData; + + if (currentlyShownAvatar.overlay == null) { + var over = Overlays.addOverlay("text3d", { + lineHeight: TEXT_LINE_HEIGHT, + color: { red: 255, green: 255, blue: 255}, + backgroundColor: {red: 0, green: 0, blue: 0}, + leftMargin: TEXT_MARGIN, + topMargin: TEXT_MARGIN, + rightMargin: TEXT_MARGIN, + bottomMargin: TEXT_MARGIN, + alpha: 0.6, + solid: true, + isFacingAvatar: true, + visible: false + }); + currentlyShownAvatar.overlay = over; + } + + var nameToShow = avatarData.displayName ? avatarData.displayName : + (avatarData.sessionDisplayName ? avatarData.sessionDisplayName : UNKNOWN_NAME); + var textSize = Overlays.textSize(currentlyShownAvatar.overlay, nameToShow); + + Overlays.editOverlay(currentlyShownAvatar.overlay, { + dimensions: { + x: textSize.width + 2 * TEXT_MARGIN, + y: TEXT_LINE_HEIGHT + 2 * TEXT_MARGIN + }, + localPosition: {x: 0, y: METERS_ABOVE_HEAD, z:0 }, + text: nameToShow, + parentID: avatarData.sessionUUID, + parentJointIndex: avatarData.getJointIndex("Head"), + visible: true + }); +} + +function touchBegin(event) { + var pickRay = Camera.computePickRay(event.x, event.y); + var avatarRay = AvatarManager.findRayIntersection(pickRay, [], rayExclusionList); + if (avatarRay.intersects) { + currentTouchToAnalize = { + touchBegin: event, + avatarRay: avatarRay + }; + printd("[AVATARNAME] touchBegin intersection " + JSON.stringify(currentTouchToAnalize)); + } else { + printd("[AVATARNAME] touchBegin no intersection"); + } +} + +function touchEnd(event) { + if (!currentTouchToAnalize) { + printd("[AVATARNAME] touchEnd no current touch"); + currentTouchToAnalize = null; + return; + } + + // manage touches only if begin an end do: + // - touch/release the same avatar + // - minimal distance (so no apparent movent was intended but a touch/click) + // - (hold or short click don't matter) + + if (Vec3.distance({x: event.x, y: event.y }, {x: currentTouchToAnalize.touchBegin.x, y: currentTouchToAnalize.touchBegin.y}) > MAX_DISTANCE_PX) { + printd("[AVATARNAME] touchEnd moved too much"); + currentTouchToAnalize = null; + return; + } + + var pickRay = Camera.computePickRay(event.x, event.y); + var avatarRay = AvatarManager.findRayIntersection(pickRay, [], rayExclusionList); + + if (avatarRay.intersects && avatarRay.avatarID == currentTouchToAnalize.avatarRay.avatarID) { + touchedAvatar(avatarRay.avatarID, AvatarManager.getAvatar(avatarRay.avatarID)); + } else { + printd("[AVATARNAME] touchEnd released outside the avatar"); + } + + currentTouchToAnalize = null; +} + +function ending() { + Controller.touchBeginEvent.disconnect(touchBegin); + Controller.touchEndEvent.disconnect(touchEnd); + Controller.mousePressEvent.disconnect(touchBegin); + Controller.mouseReleaseEvent.disconnect(touchEnd); + + if (currentlyShownAvatar.overlay) { + Overlays.deleteOverlay(currentlyShownAvatar.overlay); + currentlyShownAvatar.overlay = null; + } + if (currentlyShownAvatar.avatar) { + currentlyShownAvatar.avatar = null; + } +} + +function init() { + Controller.touchBeginEvent.connect(touchBegin); + Controller.touchEndEvent.connect(touchEnd); + Controller.mousePressEvent.connect(touchBegin); + Controller.mouseReleaseEvent.connect(touchEnd); + + Script.scriptEnding.connect(function () { + ending(); + }); +} + +init(); + +}()); // END LOCAL_SCOPE \ No newline at end of file diff --git a/scripts/system/+android/modes.js b/scripts/system/+android/modes.js index f5b3609c26..0b6e98541d 100644 --- a/scripts/system/+android/modes.js +++ b/scripts/system/+android/modes.js @@ -28,6 +28,7 @@ modeLabel[MODE_MY_VIEW]="MY VIEW"; var logEnabled = false; var radar = Script.require('./radar.js'); var uniqueColor = Script.require('./uniqueColor.js'); +var displayNames = Script.require('./displayNames.js'); function printd(str) { if (logEnabled) { From d5afb3a49b81d1b4d1070211b604e04f938a42d5 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 8 May 2018 09:04:59 -0700 Subject: [PATCH 101/152] Move non-automated tests into new folder --- .../controllers/CMakeLists.txt | 0 .../controllers/qml/main.qml | 0 .../controllers/src/main.cpp | 0 .../entities/CMakeLists.txt | 0 {tests => tests-manual}/entities/packet.bin | Bin {tests => tests-manual}/entities/src/main.cpp | 0 {tests => tests-manual}/gl/CMakeLists.txt | 0 {tests => tests-manual}/gl/src/main.cpp | 0 tests-manual/gpu-textures/CMakeLists.txt | 16 ++ .../gpu-textures/qml/textureStats.qml | 52 ++++++ tests-manual/gpu-textures/src/TestHelpers.cpp | 26 +++ tests-manual/gpu-textures/src/TestHelpers.h | 40 +++++ .../gpu-textures/src/TestTextures.cpp | 168 +++++++++++++++++ tests-manual/gpu-textures/src/TestTextures.h | 74 ++++++++ tests-manual/gpu-textures/src/TestWindow.cpp | 117 ++++++++++++ tests-manual/gpu-textures/src/TestWindow.h | 41 +++++ tests-manual/gpu-textures/src/main.cpp | 170 ++++++++++++++++++ .../gpu}/CMakeLists.txt | 0 .../gpu}/src/TestFbx.cpp | 0 .../gpu}/src/TestFbx.h | 0 .../gpu}/src/TestFloorGrid.cpp | 0 .../gpu}/src/TestFloorGrid.h | 0 .../gpu}/src/TestFloorTexture.cpp | 0 .../gpu}/src/TestFloorTexture.h | 0 .../gpu}/src/TestHelpers.cpp | 0 .../gpu}/src/TestHelpers.h | 0 .../gpu}/src/TestInstancedShapes.cpp | 0 .../gpu}/src/TestInstancedShapes.h | 0 .../gpu}/src/TestShapes.cpp | 0 .../gpu}/src/TestShapes.h | 0 .../gpu}/src/TestWindow.cpp | 0 .../gpu}/src/TestWindow.h | 0 .../gpu}/src/main.cpp | 0 {tests => tests-manual}/qml/CMakeLists.txt | 0 .../qml/qml/controls/WebEntityView.qml | 0 {tests => tests-manual}/qml/qml/main.qml | 0 .../qml/qml/qml/+android/UI.js | 0 .../qml/qml/qml/+ios/UI.js | 0 .../qml/qml/qml/+osx/UI.js | 0 .../qml/qml/qml/ButtonPage.qml | 0 .../qml/qml/qml/InputPage.qml | 0 .../qml/qml/qml/ProgressPage.qml | 0 {tests => tests-manual}/qml/qml/qml/UI.js | 0 {tests => tests-manual}/qml/src/main.cpp | 0 {tests => tests-manual}/qt59/CMakeLists.txt | 0 {tests => tests-manual}/qt59/src/main.cpp | 0 .../render-perf/CMakeLists.txt | 0 .../render-perf/src/Camera.hpp | 0 .../render-perf/src/main.cpp | 0 .../render-texture-load/CMakeLists.txt | 0 .../render-texture-load/src/GLIHelpers.cpp | 0 .../render-texture-load/src/GLIHelpers.h | 0 .../render-texture-load/src/main.cpp | 0 .../render-utils/CMakeLists.txt | 0 .../render-utils/src/main.cpp | 0 .../shaders/CMakeLists.txt | 0 {tests => tests-manual}/shaders/src/main.cpp | 0 {tests => tests-manual}/ui/CMakeLists.txt | 0 {tests => tests-manual}/ui/qml/Palettes.qml | 0 .../ui/qml/ScrollingGraph.qml | 0 {tests => tests-manual}/ui/qml/StubMenu.qml | 0 {tests => tests-manual}/ui/qml/Stubs.qml | 0 .../ui/qml/TestControllers.qml | 0 {tests => tests-manual}/ui/qml/TestDialog.qml | 0 {tests => tests-manual}/ui/qml/TestMenu.qml | 0 {tests => tests-manual}/ui/qml/TestRoot.qml | 0 .../ui/qml/controlDemo/ButtonPage.qml | 0 .../ui/qml/controlDemo/InputPage.qml | 0 .../ui/qml/controlDemo/ProgressPage.qml | 0 .../ui/qml/controlDemo/main.qml | 0 {tests => tests-manual}/ui/qml/main.qml | 0 {tests => tests-manual}/ui/qmlscratch.pro | 0 {tests => tests-manual}/ui/src/main.cpp | 0 73 files changed, 704 insertions(+) rename {tests => tests-manual}/controllers/CMakeLists.txt (100%) rename {tests => tests-manual}/controllers/qml/main.qml (100%) rename {tests => tests-manual}/controllers/src/main.cpp (100%) rename {tests => tests-manual}/entities/CMakeLists.txt (100%) rename {tests => tests-manual}/entities/packet.bin (100%) rename {tests => tests-manual}/entities/src/main.cpp (100%) rename {tests => tests-manual}/gl/CMakeLists.txt (100%) rename {tests => tests-manual}/gl/src/main.cpp (100%) create mode 100644 tests-manual/gpu-textures/CMakeLists.txt create mode 100644 tests-manual/gpu-textures/qml/textureStats.qml create mode 100644 tests-manual/gpu-textures/src/TestHelpers.cpp create mode 100644 tests-manual/gpu-textures/src/TestHelpers.h create mode 100644 tests-manual/gpu-textures/src/TestTextures.cpp create mode 100644 tests-manual/gpu-textures/src/TestTextures.h create mode 100644 tests-manual/gpu-textures/src/TestWindow.cpp create mode 100644 tests-manual/gpu-textures/src/TestWindow.h create mode 100644 tests-manual/gpu-textures/src/main.cpp rename {tests/gpu-test => tests-manual/gpu}/CMakeLists.txt (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestFbx.cpp (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestFbx.h (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestFloorGrid.cpp (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestFloorGrid.h (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestFloorTexture.cpp (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestFloorTexture.h (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestHelpers.cpp (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestHelpers.h (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestInstancedShapes.cpp (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestInstancedShapes.h (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestShapes.cpp (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestShapes.h (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestWindow.cpp (100%) rename {tests/gpu-test => tests-manual/gpu}/src/TestWindow.h (100%) rename {tests/gpu-test => tests-manual/gpu}/src/main.cpp (100%) rename {tests => tests-manual}/qml/CMakeLists.txt (100%) rename {tests => tests-manual}/qml/qml/controls/WebEntityView.qml (100%) rename {tests => tests-manual}/qml/qml/main.qml (100%) rename {tests => tests-manual}/qml/qml/qml/+android/UI.js (100%) rename {tests => tests-manual}/qml/qml/qml/+ios/UI.js (100%) rename {tests => tests-manual}/qml/qml/qml/+osx/UI.js (100%) rename {tests => tests-manual}/qml/qml/qml/ButtonPage.qml (100%) rename {tests => tests-manual}/qml/qml/qml/InputPage.qml (100%) rename {tests => tests-manual}/qml/qml/qml/ProgressPage.qml (100%) rename {tests => tests-manual}/qml/qml/qml/UI.js (100%) rename {tests => tests-manual}/qml/src/main.cpp (100%) rename {tests => tests-manual}/qt59/CMakeLists.txt (100%) rename {tests => tests-manual}/qt59/src/main.cpp (100%) rename {tests => tests-manual}/render-perf/CMakeLists.txt (100%) rename {tests => tests-manual}/render-perf/src/Camera.hpp (100%) rename {tests => tests-manual}/render-perf/src/main.cpp (100%) rename {tests => tests-manual}/render-texture-load/CMakeLists.txt (100%) rename {tests => tests-manual}/render-texture-load/src/GLIHelpers.cpp (100%) rename {tests => tests-manual}/render-texture-load/src/GLIHelpers.h (100%) rename {tests => tests-manual}/render-texture-load/src/main.cpp (100%) rename {tests => tests-manual}/render-utils/CMakeLists.txt (100%) rename {tests => tests-manual}/render-utils/src/main.cpp (100%) rename {tests => tests-manual}/shaders/CMakeLists.txt (100%) rename {tests => tests-manual}/shaders/src/main.cpp (100%) rename {tests => tests-manual}/ui/CMakeLists.txt (100%) rename {tests => tests-manual}/ui/qml/Palettes.qml (100%) rename {tests => tests-manual}/ui/qml/ScrollingGraph.qml (100%) rename {tests => tests-manual}/ui/qml/StubMenu.qml (100%) rename {tests => tests-manual}/ui/qml/Stubs.qml (100%) rename {tests => tests-manual}/ui/qml/TestControllers.qml (100%) rename {tests => tests-manual}/ui/qml/TestDialog.qml (100%) rename {tests => tests-manual}/ui/qml/TestMenu.qml (100%) rename {tests => tests-manual}/ui/qml/TestRoot.qml (100%) rename {tests => tests-manual}/ui/qml/controlDemo/ButtonPage.qml (100%) rename {tests => tests-manual}/ui/qml/controlDemo/InputPage.qml (100%) rename {tests => tests-manual}/ui/qml/controlDemo/ProgressPage.qml (100%) rename {tests => tests-manual}/ui/qml/controlDemo/main.qml (100%) rename {tests => tests-manual}/ui/qml/main.qml (100%) rename {tests => tests-manual}/ui/qmlscratch.pro (100%) rename {tests => tests-manual}/ui/src/main.cpp (100%) diff --git a/tests/controllers/CMakeLists.txt b/tests-manual/controllers/CMakeLists.txt similarity index 100% rename from tests/controllers/CMakeLists.txt rename to tests-manual/controllers/CMakeLists.txt diff --git a/tests/controllers/qml/main.qml b/tests-manual/controllers/qml/main.qml similarity index 100% rename from tests/controllers/qml/main.qml rename to tests-manual/controllers/qml/main.qml diff --git a/tests/controllers/src/main.cpp b/tests-manual/controllers/src/main.cpp similarity index 100% rename from tests/controllers/src/main.cpp rename to tests-manual/controllers/src/main.cpp diff --git a/tests/entities/CMakeLists.txt b/tests-manual/entities/CMakeLists.txt similarity index 100% rename from tests/entities/CMakeLists.txt rename to tests-manual/entities/CMakeLists.txt diff --git a/tests/entities/packet.bin b/tests-manual/entities/packet.bin similarity index 100% rename from tests/entities/packet.bin rename to tests-manual/entities/packet.bin diff --git a/tests/entities/src/main.cpp b/tests-manual/entities/src/main.cpp similarity index 100% rename from tests/entities/src/main.cpp rename to tests-manual/entities/src/main.cpp diff --git a/tests/gl/CMakeLists.txt b/tests-manual/gl/CMakeLists.txt similarity index 100% rename from tests/gl/CMakeLists.txt rename to tests-manual/gl/CMakeLists.txt diff --git a/tests/gl/src/main.cpp b/tests-manual/gl/src/main.cpp similarity index 100% rename from tests/gl/src/main.cpp rename to tests-manual/gl/src/main.cpp diff --git a/tests-manual/gpu-textures/CMakeLists.txt b/tests-manual/gpu-textures/CMakeLists.txt new file mode 100644 index 0000000000..c10f2eda3f --- /dev/null +++ b/tests-manual/gpu-textures/CMakeLists.txt @@ -0,0 +1,16 @@ +set(TARGET_NAME gpu-textures-tests) +AUTOSCRIBE_SHADER_LIB(gpu graphics render-utils) +# This is not a testcase -- just set it up as a regular hifi project +setup_hifi_project(Quick Gui Script) +setup_memory_debugger() +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") +link_hifi_libraries( + shared task networking gl + ktx gpu octree + ${PLATFORM_GL_BACKEND} +) + +set(EXTRA_DEPLOY_OPTIONS "--qmldir \"${PROJECT_SOURCE_DIR}/qml\"") +package_libraries_for_deployment() + +target_nsight() diff --git a/tests-manual/gpu-textures/qml/textureStats.qml b/tests-manual/gpu-textures/qml/textureStats.qml new file mode 100644 index 0000000000..d3700c3eac --- /dev/null +++ b/tests-manual/gpu-textures/qml/textureStats.qml @@ -0,0 +1,52 @@ +import QtQuick 2.5 +import QtQuick.Controls 2.3 + +Item { + width: 400 + height: 600 + + Column { + spacing: 10 + anchors.top: parent.top + anchors.left: parent.left + anchors.margins: 10 + + Text { text: qsTr("Total") } + Text { text: Stats.total + " MB" } + Text { text: qsTr("Allocated") } + Text { text: Stats.allocated } + Text { text: qsTr("Populated") } + Text { text: Stats.populated } + Text { text: qsTr("Pending") } + Text { text: Stats.pending } + Text { text: qsTr("Current Index") } + Text { text: Stats.index } + Text { text: qsTr("Current Source") } + Text { text: Stats.source } + Text { text: qsTr("Current Rez") } + Text { text: Stats.rez.width + " x " + Stats.rez.height } + } + + Row { + id: row1 + spacing: 10 + anchors.bottom: row2.top + anchors.left: parent.left + anchors.margins: 10 + Button { text: "1024"; onClicked: Stats.maxTextureMemory(1024); } + Button { text: "256"; onClicked: Stats.maxTextureMemory(256); } + } + + Row { + id: row2 + spacing: 10 + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.margins: 10 + Button { text: "Change Textures"; onClicked: Stats.changeTextures(); } + Button { text: "Next"; onClicked: Stats.nextTexture(); } + Button { text: "Previous"; onClicked: Stats.prevTexture(); } + } + +} + diff --git a/tests-manual/gpu-textures/src/TestHelpers.cpp b/tests-manual/gpu-textures/src/TestHelpers.cpp new file mode 100644 index 0000000000..f952a4385f --- /dev/null +++ b/tests-manual/gpu-textures/src/TestHelpers.cpp @@ -0,0 +1,26 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 "TestHelpers.h" +#include + +gpu::ShaderPointer makeShader(const std::string & vertexShaderSrc, const std::string & fragmentShaderSrc, const gpu::Shader::BindingSet & bindings) { + auto vs = gpu::Shader::createVertex(vertexShaderSrc); + auto fs = gpu::Shader::createPixel(fragmentShaderSrc); + auto shader = gpu::Shader::createProgram(vs, fs); + if (!gpu::Shader::makeProgram(*shader, bindings)) { + printf("Could not compile shader\n"); + exit(-1); + } + return shader; +} + +QString projectRootDir() { + static QString projectRootPath = QFileInfo(QFileInfo(__FILE__).absolutePath() + "/..").absoluteFilePath(); + return projectRootPath; +} diff --git a/tests-manual/gpu-textures/src/TestHelpers.h b/tests-manual/gpu-textures/src/TestHelpers.h new file mode 100644 index 0000000000..17730c3642 --- /dev/null +++ b/tests-manual/gpu-textures/src/TestHelpers.h @@ -0,0 +1,40 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 + +#include + +#include +#include +#include + +#include +#include +#include +#include + +struct RenderArgs { + gpu::ContextPointer _context; + ivec4 _viewport; + gpu::Batch* _batch; +}; + +class GpuTestBase : public QObject { +public: + virtual ~GpuTestBase() {} + virtual bool isReady() const { return true; } + virtual size_t getTestCount() const { return 1; } + virtual void renderTest(size_t test, const RenderArgs& args) = 0; + virtual QObject * statsObject() { return nullptr; } + virtual QUrl statUrl() { return QUrl(); } +}; + +uint32_t toCompactColor(const glm::vec4& color); +gpu::ShaderPointer makeShader(const std::string & vertexShaderSrc, const std::string & fragmentShaderSrc, const gpu::Shader::BindingSet & bindings); +QString projectRootDir(); diff --git a/tests-manual/gpu-textures/src/TestTextures.cpp b/tests-manual/gpu-textures/src/TestTextures.cpp new file mode 100644 index 0000000000..57cf1bccbf --- /dev/null +++ b/tests-manual/gpu-textures/src/TestTextures.cpp @@ -0,0 +1,168 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 "TestTextures.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "TestHelpers.h" + +#pragma optimize("", off) + +std::string vertexShaderSource = R"SHADER( +#line 14 +layout(location = 0) out vec2 outTexCoord0; + +const vec4 VERTICES[] = vec4[]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4( 1.0, -1.0, 0.0, 1.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4( 1.0, 1.0, 0.0, 1.0) +); + +void main() { + outTexCoord0 = VERTICES[gl_VertexID].xy; + outTexCoord0 += 1.0; + outTexCoord0 /= 2.0; + gl_Position = VERTICES[gl_VertexID]; +} +)SHADER"; + +std::string fragmentShaderSource = R"SHADER( +#line 28 + +uniform sampler2D tex; + +layout(location = 0) in vec2 inTexCoord0; +layout(location = 0) out vec4 outFragColor; + +void main() { + outFragColor = texture(tex, inTexCoord0); + outFragColor.a = 1.0; + //outFragColor.rb = inTexCoord0; +} + +)SHADER"; + +#define STAT_UPDATE(name, src) \ + { \ + auto val = src; \ + if (_##name != val) { \ + _##name = val; \ + emit name##Changed(); \ + } \ + } + + +void TextureTestStats::update(int curIndex, const gpu::TexturePointer& texture) { + STAT_UPDATE(total, (int)BYTES_TO_MB(gpu::Context::getTextureGPUMemSize())); + STAT_UPDATE(allocated, (int)gpu::Context::getTextureResourceGPUMemSize()); + STAT_UPDATE(pending, (int)gpu::Context::getTexturePendingGPUTransferMemSize()); + STAT_UPDATE(populated, (int)gpu::Context::getTextureResourcePopulatedGPUMemSize()); + STAT_UPDATE(source, texture->source().c_str()); + STAT_UPDATE(index, curIndex); + auto dims = texture->getDimensions(); + STAT_UPDATE(rez, QSize(dims.x, dims.y)); +} + +TexturesTest::TexturesTest() { + connect(&stats, &TextureTestStats::changeTextures, this, &TexturesTest::onChangeTextures); + connect(&stats, &TextureTestStats::nextTexture, this, &TexturesTest::onNextTexture); + connect(&stats, &TextureTestStats::prevTexture, this, &TexturesTest::onPrevTexture); + connect(&stats, &TextureTestStats::maxTextureMemory, this, &TexturesTest::onMaxTextureMemory); + { + auto VS = gpu::Shader::createVertex(vertexShaderSource); + auto PS = gpu::Shader::createPixel(fragmentShaderSource); + auto program = gpu::Shader::createProgram(VS, PS); + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + // If the pipeline did not exist, make it + auto state = std::make_shared(); + state->setCullMode(gpu::State::CULL_NONE); + state->setDepthTest({}); + state->setBlendFunction({ false }); + pipeline = gpu::Pipeline::create(program, state); + } + + onChangeTextures(); +} + + +void TexturesTest::renderTest(size_t testId, const RenderArgs& args) { + stats.update((int)index, textures[index]); + gpu::Batch& batch = *(args._batch); + batch.setPipeline(pipeline); + batch.setInputFormat(vertexFormat); + for (const auto& texture : textures) { + batch.setResourceTexture(0, texture); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); + } + batch.setResourceTexture(0, textures[index]); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); +} + +#define LOAD_TEXTURE_COUNT 64 + +void TexturesTest::onChangeTextures() { + static const QDir TEST_DIR("D:/ktx_texture_test"); + static std::vector ALL_TEXTURE_FILES; + if (ALL_TEXTURE_FILES.empty()) { + auto entryList = TEST_DIR.entryList({ "*.ktx" }, QDir::Filter::Files); + ALL_TEXTURE_FILES.reserve(entryList.size()); + for (auto entry : entryList) { + auto textureFile = TEST_DIR.absoluteFilePath(entry).toStdString(); + ALL_TEXTURE_FILES.push_back(textureFile); + } + } + + oldTextures.clear(); + oldTextures.swap(textures); + +#if 0 + static const std::string bad = "D:/ktx_texture_test/b4beed38675dbc7a827ecd576399c1f4.ktx"; + auto texture = gpu::Texture::unserialize(bad); + auto texelFormat = texture->getTexelFormat(); + qDebug() << texture->getTexelFormat().getSemantic(); + qDebug() << texture->getTexelFormat().getScalarCount(); + textures.push_back(texture); +#else + std::shuffle(ALL_TEXTURE_FILES.begin(), ALL_TEXTURE_FILES.end(), std::default_random_engine()); + size_t newTextureCount = std::min(ALL_TEXTURE_FILES.size(), LOAD_TEXTURE_COUNT); + for (size_t i = 0; i < newTextureCount; ++i) { + const auto& textureFile = ALL_TEXTURE_FILES[i]; + auto texture = gpu::Texture::unserialize(textureFile); + qDebug() << textureFile.c_str(); + qDebug() << texture->getTexelFormat().getSemantic(); + qDebug() << texture->getTexelFormat().getScalarCount(); + textures.push_back(texture); + } +#endif + index = 0; + qDebug() << "Done"; +} + +void TexturesTest::onNextTexture() { + index += textures.size() + 1; + index %= textures.size(); +} + +void TexturesTest::onPrevTexture() { + index += textures.size() - 1; + index %= textures.size(); +} + +void TexturesTest::onMaxTextureMemory(int maxTextureMemory) { + gpu::Texture::setAllowedGPUMemoryUsage(MB_TO_BYTES(maxTextureMemory)); +} \ No newline at end of file diff --git a/tests-manual/gpu-textures/src/TestTextures.h b/tests-manual/gpu-textures/src/TestTextures.h new file mode 100644 index 0000000000..e446ce6132 --- /dev/null +++ b/tests-manual/gpu-textures/src/TestTextures.h @@ -0,0 +1,74 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 + +#include "TestHelpers.h" + +#define STATS_PROPERTY(type, name, initialValue) \ + Q_PROPERTY(type name READ name NOTIFY name##Changed) \ +public: \ + type name() { return _##name; }; \ +private: \ + type _##name{ initialValue }; + + +class TextureTestStats : public QObject { + Q_OBJECT; + STATS_PROPERTY(int, pending, 0) + STATS_PROPERTY(int, total, 0) + STATS_PROPERTY(int, populated, 0) + STATS_PROPERTY(int, allocated, 0) + STATS_PROPERTY(int, index, 0) + + STATS_PROPERTY(QString, source, QString()) + STATS_PROPERTY(QSize, rez, QSize(0, 0)) + +public: + void update(int index, const gpu::TexturePointer& texture); + +signals: + void pendingChanged(); + void totalChanged(); + void populatedChanged(); + void allocatedChanged(); + void changeTextures(); + void rezChanged(); + void indexChanged(); + void sourceChanged(); + void maxTextureMemory(int); + + void nextTexture(); + void prevTexture(); +}; + + +class TexturesTest : public GpuTestBase { + Q_OBJECT + + gpu::Stream::FormatPointer vertexFormat { std::make_shared() }; + std::vector textures; + std::vector oldTextures; + gpu::PipelinePointer pipeline; + TextureTestStats stats; + size_t index{ 0 }; + +public: + TexturesTest(); + QObject* statsObject() override { return &stats; } + QUrl statUrl() override { return QUrl::fromLocalFile(projectRootDir() + "/qml/textureStats.qml"); } + void renderTest(size_t testId, const RenderArgs& args) override; + +protected slots: + void onChangeTextures(); + void onMaxTextureMemory(int newValue); + void onNextTexture(); + void onPrevTexture(); + +}; + + diff --git a/tests-manual/gpu-textures/src/TestWindow.cpp b/tests-manual/gpu-textures/src/TestWindow.cpp new file mode 100644 index 0000000000..038b0b9b80 --- /dev/null +++ b/tests-manual/gpu-textures/src/TestWindow.cpp @@ -0,0 +1,117 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 "TestWindow.h" + +#include +#include + +#include +#include + +#include + +#include + +TestWindow::TestWindow() { + + auto timer = new QTimer(this); + timer->setTimerType(Qt::PreciseTimer); + timer->setInterval(5); + connect(timer, &QTimer::timeout, [&] { draw(); }); + timer->start(); + + connect(qApp, &QCoreApplication::aboutToQuit, [this, timer] { + timer->stop(); + _aboutToQuit = true; + }); + + setSurfaceType(QSurface::OpenGLSurface); + + QSurfaceFormat format = getDefaultOpenGLSurfaceFormat(); + format.setOption(QSurfaceFormat::DebugContext); + setFormat(format); + _glContext.setFormat(format); + _glContext.create(); + _glContext.makeCurrent(this); + + show(); +} + +void TestWindow::initGl() { + _glContext.makeCurrent(this); + gl::initModuleGl(); + gpu::Context::init(); + _renderArgs->_context = std::make_shared(); + _glContext.makeCurrent(this); + resize(QSize(800, 600)); +} + +void TestWindow::resizeWindow(const QSize& size) { + _size = size; + _renderArgs->_viewport = ivec4(0, 0, _size.width(), _size.height()); +} + +void TestWindow::beginFrame() { + _renderArgs->_context->recycle(); + _renderArgs->_context->beginFrame(); + gpu::doInBatch("TestWindow::beginFrame", _renderArgs->_context, [&](gpu::Batch& batch) { + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLORS, { 0.0f, 0.1f, 0.2f, 1.0f }); + batch.clearDepthFramebuffer(1e4); + batch.setViewportTransform({ 0, 0, _size.width() * devicePixelRatio(), _size.height() * devicePixelRatio() }); + }); + + gpu::doInBatch("TestWindow::beginFrame", _renderArgs->_context, [&](gpu::Batch& batch) { + batch.setViewportTransform(_renderArgs->_viewport); + batch.setStateScissorRect(_renderArgs->_viewport); + batch.setProjectionTransform(_projectionMatrix); + }); +} + +void TestWindow::endFrame() { + gpu::doInBatch("TestWindow::endFrame::finish", _renderArgs->_context, [&](gpu::Batch& batch) { + batch.resetStages(); + }); + auto framePointer = _renderArgs->_context->endFrame(); + _renderArgs->_context->consumeFrameUpdates(framePointer); + _renderArgs->_context->executeFrame(framePointer); + _glContext.swapBuffers(this); +} + +void TestWindow::draw() { + if (_aboutToQuit) { + return; + } + + // Attempting to draw before we're visible and have a valid size will + // produce GL errors. + if (!isVisible() || _size.width() <= 0 || _size.height() <= 0) { + return; + } + + if (!_glContext.makeCurrent(this)) { + return; + } + + static std::once_flag once; + std::call_once(once, [&] { initGl(); }); + beginFrame(); + + renderFrame(); + + endFrame(); +} + +void TestWindow::resizeEvent(QResizeEvent* ev) { + resizeWindow(ev->size()); + float fov_degrees = 60.0f; + float aspect_ratio = (float)_size.width() / _size.height(); + float near_clip = 0.1f; + float far_clip = 1000.0f; + _projectionMatrix = glm::perspective(glm::radians(fov_degrees), aspect_ratio, near_clip, far_clip); +} diff --git a/tests-manual/gpu-textures/src/TestWindow.h b/tests-manual/gpu-textures/src/TestWindow.h new file mode 100644 index 0000000000..00bbf03836 --- /dev/null +++ b/tests-manual/gpu-textures/src/TestWindow.h @@ -0,0 +1,41 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 + +#include +#include + +#include +#include +#include +#include "TestHelpers.h" + +#define DEFERRED_LIGHTING + +class TestWindow : public QWindow { +protected: + QOpenGLContextWrapper _glContext; + QSize _size; + glm::mat4 _projectionMatrix; + bool _aboutToQuit { false }; + std::shared_ptr _renderArgs{ std::make_shared() }; + + TestWindow(); + virtual void initGl(); + virtual void renderFrame() = 0; + +private: + void resizeWindow(const QSize& size); + + void beginFrame(); + void endFrame(); + void draw(); + void resizeEvent(QResizeEvent* ev) override; +}; + diff --git a/tests-manual/gpu-textures/src/main.cpp b/tests-manual/gpu-textures/src/main.cpp new file mode 100644 index 0000000000..3d0051dc1d --- /dev/null +++ b/tests-manual/gpu-textures/src/main.cpp @@ -0,0 +1,170 @@ +// +// main.cpp +// tests/gpu-test/src +// +// Copyright 2015 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "TestWindow.h" +#include "TestTextures.h" + +using TestBuilder = std::function; +using TestBuilders = std::list; + +#define INTERACTIVE + +class MyTestWindow : public TestWindow { + using Parent = TestWindow; + TestBuilders _testBuilders; + GpuTestBase* _currentTest{ nullptr }; + size_t _currentTestId{ 0 }; + size_t _currentMaxTests{ 0 }; + glm::mat4 _camera; + QTime _time; + + void initGl() override { + Parent::initGl(); + _time.start(); + updateCamera(); + _testBuilders = TestBuilders({ + [] { return new TexturesTest(); }, + }); + } + + void updateCamera() { + float t = _time.elapsed() * 1e-3f; + glm::vec3 unitscale{ 1.0f }; + glm::vec3 up{ 0.0f, 1.0f, 0.0f }; + + float distance = 3.0f; + glm::vec3 camera_position{ distance * sinf(t), 0.5f, distance * cosf(t) }; + + static const vec3 camera_focus(0); + static const vec3 camera_up(0, 1, 0); + _camera = glm::inverse(glm::lookAt(camera_position, camera_focus, up)); + + ViewFrustum frustum; + frustum.setPosition(camera_position); + frustum.setOrientation(glm::quat_cast(_camera)); + frustum.setProjection(_projectionMatrix); + } + + void renderFrame() override { + updateCamera(); + + while ((!_currentTest || (_currentTestId >= _currentMaxTests)) && !_testBuilders.empty()) { + if (_currentTest) { + delete _currentTest; + _currentTest = nullptr; + } + + _currentTest = _testBuilders.front()(); + _testBuilders.pop_front(); + + if (_currentTest) { + auto statsObject = _currentTest->statsObject(); + QUrl url = _currentTest->statUrl(); + if (statsObject) { + auto screens = qApp->screens(); + auto primaryScreen = qApp->primaryScreen(); + auto targetScreen = primaryScreen; + for (const auto& screen : screens) { + if (screen == primaryScreen) { + continue; + } + targetScreen = screen; + break; + } + + auto destPoint = targetScreen->availableGeometry().topLeft(); + QQuickView* view = new QQuickView(); + view->rootContext()->setContextProperty("Stats", statsObject); + view->setSource(url); + view->show(); + view->setPosition({ destPoint.x() + 100, destPoint.y() + 100 }); + } + _currentMaxTests = _currentTest->getTestCount(); + _currentTestId = 0; + } + } + + if (!_currentTest && _testBuilders.empty()) { + qApp->quit(); + return; + } + + // Tests might need to wait for resources to download + if (!_currentTest->isReady()) { + return; + } + + gpu::doInBatch("main::renderFrame", _renderArgs->_context, [&](gpu::Batch& batch) { + batch.setViewTransform(_camera); + _renderArgs->_batch = &batch; + _currentTest->renderTest(_currentTestId, *_renderArgs); + _renderArgs->_batch = nullptr; + }); + } +}; + +int main(int argc, char** argv) { + setupHifiApplication("GPU Test"); + qputenv("HIFI_DEBUG_OPENGL", QByteArray("1")); + QApplication app(argc, argv); + MyTestWindow window; + app.exec(); + + return 0; +} diff --git a/tests/gpu-test/CMakeLists.txt b/tests-manual/gpu/CMakeLists.txt similarity index 100% rename from tests/gpu-test/CMakeLists.txt rename to tests-manual/gpu/CMakeLists.txt diff --git a/tests/gpu-test/src/TestFbx.cpp b/tests-manual/gpu/src/TestFbx.cpp similarity index 100% rename from tests/gpu-test/src/TestFbx.cpp rename to tests-manual/gpu/src/TestFbx.cpp diff --git a/tests/gpu-test/src/TestFbx.h b/tests-manual/gpu/src/TestFbx.h similarity index 100% rename from tests/gpu-test/src/TestFbx.h rename to tests-manual/gpu/src/TestFbx.h diff --git a/tests/gpu-test/src/TestFloorGrid.cpp b/tests-manual/gpu/src/TestFloorGrid.cpp similarity index 100% rename from tests/gpu-test/src/TestFloorGrid.cpp rename to tests-manual/gpu/src/TestFloorGrid.cpp diff --git a/tests/gpu-test/src/TestFloorGrid.h b/tests-manual/gpu/src/TestFloorGrid.h similarity index 100% rename from tests/gpu-test/src/TestFloorGrid.h rename to tests-manual/gpu/src/TestFloorGrid.h diff --git a/tests/gpu-test/src/TestFloorTexture.cpp b/tests-manual/gpu/src/TestFloorTexture.cpp similarity index 100% rename from tests/gpu-test/src/TestFloorTexture.cpp rename to tests-manual/gpu/src/TestFloorTexture.cpp diff --git a/tests/gpu-test/src/TestFloorTexture.h b/tests-manual/gpu/src/TestFloorTexture.h similarity index 100% rename from tests/gpu-test/src/TestFloorTexture.h rename to tests-manual/gpu/src/TestFloorTexture.h diff --git a/tests/gpu-test/src/TestHelpers.cpp b/tests-manual/gpu/src/TestHelpers.cpp similarity index 100% rename from tests/gpu-test/src/TestHelpers.cpp rename to tests-manual/gpu/src/TestHelpers.cpp diff --git a/tests/gpu-test/src/TestHelpers.h b/tests-manual/gpu/src/TestHelpers.h similarity index 100% rename from tests/gpu-test/src/TestHelpers.h rename to tests-manual/gpu/src/TestHelpers.h diff --git a/tests/gpu-test/src/TestInstancedShapes.cpp b/tests-manual/gpu/src/TestInstancedShapes.cpp similarity index 100% rename from tests/gpu-test/src/TestInstancedShapes.cpp rename to tests-manual/gpu/src/TestInstancedShapes.cpp diff --git a/tests/gpu-test/src/TestInstancedShapes.h b/tests-manual/gpu/src/TestInstancedShapes.h similarity index 100% rename from tests/gpu-test/src/TestInstancedShapes.h rename to tests-manual/gpu/src/TestInstancedShapes.h diff --git a/tests/gpu-test/src/TestShapes.cpp b/tests-manual/gpu/src/TestShapes.cpp similarity index 100% rename from tests/gpu-test/src/TestShapes.cpp rename to tests-manual/gpu/src/TestShapes.cpp diff --git a/tests/gpu-test/src/TestShapes.h b/tests-manual/gpu/src/TestShapes.h similarity index 100% rename from tests/gpu-test/src/TestShapes.h rename to tests-manual/gpu/src/TestShapes.h diff --git a/tests/gpu-test/src/TestWindow.cpp b/tests-manual/gpu/src/TestWindow.cpp similarity index 100% rename from tests/gpu-test/src/TestWindow.cpp rename to tests-manual/gpu/src/TestWindow.cpp diff --git a/tests/gpu-test/src/TestWindow.h b/tests-manual/gpu/src/TestWindow.h similarity index 100% rename from tests/gpu-test/src/TestWindow.h rename to tests-manual/gpu/src/TestWindow.h diff --git a/tests/gpu-test/src/main.cpp b/tests-manual/gpu/src/main.cpp similarity index 100% rename from tests/gpu-test/src/main.cpp rename to tests-manual/gpu/src/main.cpp diff --git a/tests/qml/CMakeLists.txt b/tests-manual/qml/CMakeLists.txt similarity index 100% rename from tests/qml/CMakeLists.txt rename to tests-manual/qml/CMakeLists.txt diff --git a/tests/qml/qml/controls/WebEntityView.qml b/tests-manual/qml/qml/controls/WebEntityView.qml similarity index 100% rename from tests/qml/qml/controls/WebEntityView.qml rename to tests-manual/qml/qml/controls/WebEntityView.qml diff --git a/tests/qml/qml/main.qml b/tests-manual/qml/qml/main.qml similarity index 100% rename from tests/qml/qml/main.qml rename to tests-manual/qml/qml/main.qml diff --git a/tests/qml/qml/qml/+android/UI.js b/tests-manual/qml/qml/qml/+android/UI.js similarity index 100% rename from tests/qml/qml/qml/+android/UI.js rename to tests-manual/qml/qml/qml/+android/UI.js diff --git a/tests/qml/qml/qml/+ios/UI.js b/tests-manual/qml/qml/qml/+ios/UI.js similarity index 100% rename from tests/qml/qml/qml/+ios/UI.js rename to tests-manual/qml/qml/qml/+ios/UI.js diff --git a/tests/qml/qml/qml/+osx/UI.js b/tests-manual/qml/qml/qml/+osx/UI.js similarity index 100% rename from tests/qml/qml/qml/+osx/UI.js rename to tests-manual/qml/qml/qml/+osx/UI.js diff --git a/tests/qml/qml/qml/ButtonPage.qml b/tests-manual/qml/qml/qml/ButtonPage.qml similarity index 100% rename from tests/qml/qml/qml/ButtonPage.qml rename to tests-manual/qml/qml/qml/ButtonPage.qml diff --git a/tests/qml/qml/qml/InputPage.qml b/tests-manual/qml/qml/qml/InputPage.qml similarity index 100% rename from tests/qml/qml/qml/InputPage.qml rename to tests-manual/qml/qml/qml/InputPage.qml diff --git a/tests/qml/qml/qml/ProgressPage.qml b/tests-manual/qml/qml/qml/ProgressPage.qml similarity index 100% rename from tests/qml/qml/qml/ProgressPage.qml rename to tests-manual/qml/qml/qml/ProgressPage.qml diff --git a/tests/qml/qml/qml/UI.js b/tests-manual/qml/qml/qml/UI.js similarity index 100% rename from tests/qml/qml/qml/UI.js rename to tests-manual/qml/qml/qml/UI.js diff --git a/tests/qml/src/main.cpp b/tests-manual/qml/src/main.cpp similarity index 100% rename from tests/qml/src/main.cpp rename to tests-manual/qml/src/main.cpp diff --git a/tests/qt59/CMakeLists.txt b/tests-manual/qt59/CMakeLists.txt similarity index 100% rename from tests/qt59/CMakeLists.txt rename to tests-manual/qt59/CMakeLists.txt diff --git a/tests/qt59/src/main.cpp b/tests-manual/qt59/src/main.cpp similarity index 100% rename from tests/qt59/src/main.cpp rename to tests-manual/qt59/src/main.cpp diff --git a/tests/render-perf/CMakeLists.txt b/tests-manual/render-perf/CMakeLists.txt similarity index 100% rename from tests/render-perf/CMakeLists.txt rename to tests-manual/render-perf/CMakeLists.txt diff --git a/tests/render-perf/src/Camera.hpp b/tests-manual/render-perf/src/Camera.hpp similarity index 100% rename from tests/render-perf/src/Camera.hpp rename to tests-manual/render-perf/src/Camera.hpp diff --git a/tests/render-perf/src/main.cpp b/tests-manual/render-perf/src/main.cpp similarity index 100% rename from tests/render-perf/src/main.cpp rename to tests-manual/render-perf/src/main.cpp diff --git a/tests/render-texture-load/CMakeLists.txt b/tests-manual/render-texture-load/CMakeLists.txt similarity index 100% rename from tests/render-texture-load/CMakeLists.txt rename to tests-manual/render-texture-load/CMakeLists.txt diff --git a/tests/render-texture-load/src/GLIHelpers.cpp b/tests-manual/render-texture-load/src/GLIHelpers.cpp similarity index 100% rename from tests/render-texture-load/src/GLIHelpers.cpp rename to tests-manual/render-texture-load/src/GLIHelpers.cpp diff --git a/tests/render-texture-load/src/GLIHelpers.h b/tests-manual/render-texture-load/src/GLIHelpers.h similarity index 100% rename from tests/render-texture-load/src/GLIHelpers.h rename to tests-manual/render-texture-load/src/GLIHelpers.h diff --git a/tests/render-texture-load/src/main.cpp b/tests-manual/render-texture-load/src/main.cpp similarity index 100% rename from tests/render-texture-load/src/main.cpp rename to tests-manual/render-texture-load/src/main.cpp diff --git a/tests/render-utils/CMakeLists.txt b/tests-manual/render-utils/CMakeLists.txt similarity index 100% rename from tests/render-utils/CMakeLists.txt rename to tests-manual/render-utils/CMakeLists.txt diff --git a/tests/render-utils/src/main.cpp b/tests-manual/render-utils/src/main.cpp similarity index 100% rename from tests/render-utils/src/main.cpp rename to tests-manual/render-utils/src/main.cpp diff --git a/tests/shaders/CMakeLists.txt b/tests-manual/shaders/CMakeLists.txt similarity index 100% rename from tests/shaders/CMakeLists.txt rename to tests-manual/shaders/CMakeLists.txt diff --git a/tests/shaders/src/main.cpp b/tests-manual/shaders/src/main.cpp similarity index 100% rename from tests/shaders/src/main.cpp rename to tests-manual/shaders/src/main.cpp diff --git a/tests/ui/CMakeLists.txt b/tests-manual/ui/CMakeLists.txt similarity index 100% rename from tests/ui/CMakeLists.txt rename to tests-manual/ui/CMakeLists.txt diff --git a/tests/ui/qml/Palettes.qml b/tests-manual/ui/qml/Palettes.qml similarity index 100% rename from tests/ui/qml/Palettes.qml rename to tests-manual/ui/qml/Palettes.qml diff --git a/tests/ui/qml/ScrollingGraph.qml b/tests-manual/ui/qml/ScrollingGraph.qml similarity index 100% rename from tests/ui/qml/ScrollingGraph.qml rename to tests-manual/ui/qml/ScrollingGraph.qml diff --git a/tests/ui/qml/StubMenu.qml b/tests-manual/ui/qml/StubMenu.qml similarity index 100% rename from tests/ui/qml/StubMenu.qml rename to tests-manual/ui/qml/StubMenu.qml diff --git a/tests/ui/qml/Stubs.qml b/tests-manual/ui/qml/Stubs.qml similarity index 100% rename from tests/ui/qml/Stubs.qml rename to tests-manual/ui/qml/Stubs.qml diff --git a/tests/ui/qml/TestControllers.qml b/tests-manual/ui/qml/TestControllers.qml similarity index 100% rename from tests/ui/qml/TestControllers.qml rename to tests-manual/ui/qml/TestControllers.qml diff --git a/tests/ui/qml/TestDialog.qml b/tests-manual/ui/qml/TestDialog.qml similarity index 100% rename from tests/ui/qml/TestDialog.qml rename to tests-manual/ui/qml/TestDialog.qml diff --git a/tests/ui/qml/TestMenu.qml b/tests-manual/ui/qml/TestMenu.qml similarity index 100% rename from tests/ui/qml/TestMenu.qml rename to tests-manual/ui/qml/TestMenu.qml diff --git a/tests/ui/qml/TestRoot.qml b/tests-manual/ui/qml/TestRoot.qml similarity index 100% rename from tests/ui/qml/TestRoot.qml rename to tests-manual/ui/qml/TestRoot.qml diff --git a/tests/ui/qml/controlDemo/ButtonPage.qml b/tests-manual/ui/qml/controlDemo/ButtonPage.qml similarity index 100% rename from tests/ui/qml/controlDemo/ButtonPage.qml rename to tests-manual/ui/qml/controlDemo/ButtonPage.qml diff --git a/tests/ui/qml/controlDemo/InputPage.qml b/tests-manual/ui/qml/controlDemo/InputPage.qml similarity index 100% rename from tests/ui/qml/controlDemo/InputPage.qml rename to tests-manual/ui/qml/controlDemo/InputPage.qml diff --git a/tests/ui/qml/controlDemo/ProgressPage.qml b/tests-manual/ui/qml/controlDemo/ProgressPage.qml similarity index 100% rename from tests/ui/qml/controlDemo/ProgressPage.qml rename to tests-manual/ui/qml/controlDemo/ProgressPage.qml diff --git a/tests/ui/qml/controlDemo/main.qml b/tests-manual/ui/qml/controlDemo/main.qml similarity index 100% rename from tests/ui/qml/controlDemo/main.qml rename to tests-manual/ui/qml/controlDemo/main.qml diff --git a/tests/ui/qml/main.qml b/tests-manual/ui/qml/main.qml similarity index 100% rename from tests/ui/qml/main.qml rename to tests-manual/ui/qml/main.qml diff --git a/tests/ui/qmlscratch.pro b/tests-manual/ui/qmlscratch.pro similarity index 100% rename from tests/ui/qmlscratch.pro rename to tests-manual/ui/qmlscratch.pro diff --git a/tests/ui/src/main.cpp b/tests-manual/ui/src/main.cpp similarity index 100% rename from tests/ui/src/main.cpp rename to tests-manual/ui/src/main.cpp From 6e16109fa45dfc5821bc59d9dac624ebab478321 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 8 May 2018 09:11:13 -0700 Subject: [PATCH 102/152] Fix unit test compile failures and crashes --- tests/animation/src/AnimTests.cpp | 1 + tests/ktx/src/KtxTests.cpp | 4 +++- tests/networking/src/ResourceTests.cpp | 21 ++++++++++++++++----- tests/networking/src/ResourceTests.h | 1 + 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/tests/animation/src/AnimTests.cpp b/tests/animation/src/AnimTests.cpp index fe54ac3781..432129594a 100644 --- a/tests/animation/src/AnimTests.cpp +++ b/tests/animation/src/AnimTests.cpp @@ -39,6 +39,7 @@ void AnimTests::initTestCase() { void AnimTests::cleanupTestCase() { //DependencyManager::destroy(); + DependencyManager::get()->cleanup(); } void AnimTests::testClipInternalState() { diff --git a/tests/ktx/src/KtxTests.cpp b/tests/ktx/src/KtxTests.cpp index 65d9cbec3d..5158ad2fd4 100644 --- a/tests/ktx/src/KtxTests.cpp +++ b/tests/ktx/src/KtxTests.cpp @@ -76,7 +76,9 @@ void KtxTests::testKtxEvalFunctions() { void KtxTests::testKtxSerialization() { const QString TEST_IMAGE = getRootPath() + "/scripts/developer/tests/cube_texture.png"; QImage image(TEST_IMAGE); - gpu::TexturePointer testTexture = image::TextureUsage::process2DTextureColorFromImage(image, TEST_IMAGE.toStdString(), true); + std::atomic abortSignal; + gpu::TexturePointer testTexture = + image::TextureUsage::process2DTextureColorFromImage(std::move(image), TEST_IMAGE.toStdString(), true, abortSignal); auto ktxMemory = gpu::Texture::serialize(*testTexture); QVERIFY(ktxMemory.get()); diff --git a/tests/networking/src/ResourceTests.cpp b/tests/networking/src/ResourceTests.cpp index 864d7c9939..6af3629bc7 100644 --- a/tests/networking/src/ResourceTests.cpp +++ b/tests/networking/src/ResourceTests.cpp @@ -11,16 +11,23 @@ #include -#include "ResourceCache.h" -#include "NetworkAccessManager.h" -#include "DependencyManager.h" +#include +#include +#include +#include +#include +#include QTEST_MAIN(ResourceTests) void ResourceTests::initTestCase() { - auto resourceCacheSharedItems = DependencyManager::set(); - + //DependencyManager::set(); + DependencyManager::set(); + DependencyManager::registerInheritance(); + DependencyManager::set(NodeType::Agent, INVALID_PORT); + DependencyManager::set(); + DependencyManager::set(); const qint64 MAXIMUM_CACHE_SIZE = 1024 * 1024 * 1024; // 1GB // set up the file cache @@ -34,6 +41,10 @@ void ResourceTests::initTestCase() { networkAccessManager.setCache(cache); } +void ResourceTests::cleanupTestCase() { + DependencyManager::get()->cleanup(); +} + static QSharedPointer resource; diff --git a/tests/networking/src/ResourceTests.h b/tests/networking/src/ResourceTests.h index 32fc151982..59675816ba 100644 --- a/tests/networking/src/ResourceTests.h +++ b/tests/networking/src/ResourceTests.h @@ -18,6 +18,7 @@ private slots: void initTestCase(); void downloadFirst(); void downloadAgain(); + void cleanupTestCase(); }; #endif // hifi_ResourceTests_h From f206456cddfd93f063632ed0e1c2e92dddcfa419 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 8 May 2018 10:18:08 -0700 Subject: [PATCH 103/152] Restoring manual tests to solution, removing dead tests --- CMakeLists.txt | 1 + tests-manual/CMakeLists.txt | 8 ++++ tests-manual/qt59/CMakeLists.txt | 22 ---------- tests-manual/qt59/src/main.cpp | 73 -------------------------------- tests-manual/ui/CMakeLists.txt | 1 - 5 files changed, 9 insertions(+), 96 deletions(-) create mode 100644 tests-manual/CMakeLists.txt delete mode 100644 tests-manual/qt59/CMakeLists.txt delete mode 100644 tests-manual/qt59/src/main.cpp delete mode 100644 tests-manual/ui/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 93b784b462..69ea0b7fd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,7 @@ add_subdirectory(tools) if (BUILD_TESTS) add_subdirectory(tests) + add_subdirectory(tests-manual) endif() if (BUILD_INSTALLER) diff --git a/tests-manual/CMakeLists.txt b/tests-manual/CMakeLists.txt new file mode 100644 index 0000000000..bc64183298 --- /dev/null +++ b/tests-manual/CMakeLists.txt @@ -0,0 +1,8 @@ +# add the manual test directories +file(GLOB TEST_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") +foreach(DIR ${TEST_SUBDIRS}) + if((IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${DIR}") AND (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${DIR}/CMakeLists.txt")) + set(TEST_PROJ_NAME ${DIR}) + add_subdirectory(${DIR}) + endif() +endforeach() diff --git a/tests-manual/qt59/CMakeLists.txt b/tests-manual/qt59/CMakeLists.txt deleted file mode 100644 index e3450ae069..0000000000 --- a/tests-manual/qt59/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ - -set(TARGET_NAME qt59) - -if (WIN32) - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4049 /ignore:4217") -endif() - -setup_memory_debugger() - -# This is not a testcase -- just set it up as a regular hifi project -setup_hifi_project(Gui) -set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") - - -# link in the shared libraries -link_hifi_libraries(shared networking) - -if (WIN32) - add_dependency_external_projects(wasapi) -endif() - -package_libraries_for_deployment() diff --git a/tests-manual/qt59/src/main.cpp b/tests-manual/qt59/src/main.cpp deleted file mode 100644 index 19b922de9f..0000000000 --- a/tests-manual/qt59/src/main.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// -// Created by Bradley Austin Davis on 2017/06/06 -// Copyright 2013-2017 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 - -#include - -#include -#include -#include -#include - -#include - - -class Qt59TestApp : public QCoreApplication { - Q_OBJECT -public: - Qt59TestApp(int argc, char* argv[]); - ~Qt59TestApp(); - -private: - void finish(int exitCode); -}; - - - -Qt59TestApp::Qt59TestApp(int argc, char* argv[]) : - QCoreApplication(argc, argv) -{ - DependencyManager::registerInheritance(); - DependencyManager::set([&] { return QString("Mozilla/5.0 (HighFidelityACClient)"); }); - DependencyManager::set(); - DependencyManager::set(NodeType::Agent, 0); - auto nodeList = DependencyManager::get(); - nodeList->startThread(); - auto messagesClient = DependencyManager::set(); - messagesClient->startThread(); - QTimer::singleShot(1000, [this] { finish(0); }); -} - -Qt59TestApp::~Qt59TestApp() { -} - - -void Qt59TestApp::finish(int exitCode) { - auto nodeList = DependencyManager::get(); - - // send the domain a disconnect packet, force stoppage of domain-server check-ins - nodeList->getDomainHandler().disconnect(); - nodeList->setIsShuttingDown(true); - nodeList->getPacketReceiver().setShouldDropPackets(true); - - // remove the NodeList from the DependencyManager - DependencyManager::destroy(); - QCoreApplication::exit(exitCode); -} - - -int main(int argc, char * argv[]) { - setupHifiApplication("Qt59Test"); - - Qt59TestApp app(argc, argv); - - return app.exec(); -} - -#include "main.moc" diff --git a/tests-manual/ui/CMakeLists.txt b/tests-manual/ui/CMakeLists.txt deleted file mode 100644 index 0a5d6796e0..0000000000 --- a/tests-manual/ui/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -# This folder contains code for testing the QML UI using Qt Creator. It is not intended to be included in the CMake project From e9dc3c650b57e1610e95b4e7d72b2c022c5e7cbb Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 8 May 2018 15:31:17 -0700 Subject: [PATCH 104/152] Breakup building and testing --- cmake/macros/SetupHifiTestCase.cmake | 5 ++--- tests/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cmake/macros/SetupHifiTestCase.cmake b/cmake/macros/SetupHifiTestCase.cmake index 6c7d38e19c..b0edb41e36 100644 --- a/cmake/macros/SetupHifiTestCase.cmake +++ b/cmake/macros/SetupHifiTestCase.cmake @@ -124,15 +124,14 @@ macro(SETUP_HIFI_TESTCASE) # This target will also build + run the other test targets using ctest when built. add_custom_target(${TEST_TARGET} - COMMAND ctest . SOURCES ${TEST_PROJ_SRC_FILES} # display source files under the testcase target DEPENDS ${${TEST_PROJ_NAME}_TARGETS}) + set_target_properties(${TEST_TARGET} PROPERTIES + FOLDER "Tests" EXCLUDE_FROM_DEFAULT_BUILD TRUE EXCLUDE_FROM_ALL TRUE) - set_target_properties(${TEST_TARGET} PROPERTIES FOLDER "Tests") - list (APPEND ALL_TEST_TARGETS ${TEST_TARGET}) set(ALL_TEST_TARGETS "${ALL_TEST_TARGETS}" PARENT_SCOPE) else () diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a8b0727e3d..bc11580979 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -27,9 +27,9 @@ set_target_properties("test-extensions" PROPERTIES FOLDER "Tests") # set (ALL_TEST_TARGETS "${ALL_TEST_TARGETS}" PARENT_SCOPE) # copies this back to parent scope # add_custom_target("all-tests" - COMMAND ctest . DEPENDS "${ALL_TEST_TARGETS}") -set_target_properties("all-tests" PROPERTIES FOLDER "hidden/test-targets") + set_target_properties("all-tests" PROPERTIES + FOLDER "hidden/test-targets" EXCLUDE_FROM_DEFAULT_BUILD TRUE EXCLUDE_FROM_ALL TRUE) From 12ae44c14f4424503ab5562a2b0706431173cc68 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 8 May 2018 15:34:51 -0700 Subject: [PATCH 105/152] Remove debugging pragma --- tests-manual/gpu-textures/src/TestTextures.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests-manual/gpu-textures/src/TestTextures.cpp b/tests-manual/gpu-textures/src/TestTextures.cpp index 57cf1bccbf..7aedb506da 100644 --- a/tests-manual/gpu-textures/src/TestTextures.cpp +++ b/tests-manual/gpu-textures/src/TestTextures.cpp @@ -19,8 +19,6 @@ #include "TestHelpers.h" -#pragma optimize("", off) - std::string vertexShaderSource = R"SHADER( #line 14 layout(location = 0) out vec2 outTexCoord0; @@ -165,4 +163,4 @@ void TexturesTest::onPrevTexture() { void TexturesTest::onMaxTextureMemory(int maxTextureMemory) { gpu::Texture::setAllowedGPUMemoryUsage(MB_TO_BYTES(maxTextureMemory)); -} \ No newline at end of file +} From 1d403b4d6781b5c728d29fb46d8634c10f714d0f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 8 May 2018 19:41:07 -0700 Subject: [PATCH 106/152] Add texture transfer testing --- libraries/gl/src/gl/OffscreenGLCanvas.cpp | 15 +- tests/gpu/CMakeLists.txt | 9 + tests/gpu/src/TextureTest.cpp | 208 ++++++++++++++++++++++ tests/gpu/src/TextureTest.h | 37 ++++ 4 files changed, 263 insertions(+), 6 deletions(-) create mode 100644 tests/gpu/CMakeLists.txt create mode 100644 tests/gpu/src/TextureTest.cpp create mode 100644 tests/gpu/src/TextureTest.h diff --git a/libraries/gl/src/gl/OffscreenGLCanvas.cpp b/libraries/gl/src/gl/OffscreenGLCanvas.cpp index 91f7954943..6598a26c99 100644 --- a/libraries/gl/src/gl/OffscreenGLCanvas.cpp +++ b/libraries/gl/src/gl/OffscreenGLCanvas.cpp @@ -103,12 +103,15 @@ void OffscreenGLCanvas::onMessageLogged(const QOpenGLDebugMessage& debugMessage) bool OffscreenGLCanvas::makeCurrent() { bool result = _context->makeCurrent(_offscreenSurface); - std::call_once(_reportOnce, []{ - qCDebug(glLogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); - qCDebug(glLogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); - qCDebug(glLogging) << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR)); - qCDebug(glLogging) << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); - }); + if (glGetString) { + std::call_once(_reportOnce, [] { + qCDebug(glLogging) << "GL Version: " << QString((const char*)glGetString(GL_VERSION)); + qCDebug(glLogging) << "GL Shader Language Version: " + << QString((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION)); + qCDebug(glLogging) << "GL Vendor: " << QString((const char*)glGetString(GL_VENDOR)); + qCDebug(glLogging) << "GL Renderer: " << QString((const char*)glGetString(GL_RENDERER)); + }); + } return result; } diff --git a/tests/gpu/CMakeLists.txt b/tests/gpu/CMakeLists.txt new file mode 100644 index 0000000000..6974953b40 --- /dev/null +++ b/tests/gpu/CMakeLists.txt @@ -0,0 +1,9 @@ +# Declare dependencies +macro (setup_testcase_dependencies) + # link in the shared libraries + link_hifi_libraries(shared ktx gpu gl ${PLATFORM_GL_BACKEND}) + package_libraries_for_deployment() + target_opengl() +endmacro () + +setup_hifi_testcase() diff --git a/tests/gpu/src/TextureTest.cpp b/tests/gpu/src/TextureTest.cpp new file mode 100644 index 0000000000..9377a18244 --- /dev/null +++ b/tests/gpu/src/TextureTest.cpp @@ -0,0 +1,208 @@ +// +// Created by Bradley Austin Davis on 2018/01/11 +// Copyright 2014 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 "TextureTest.h" + +#include +#include +#include +#include +#include + +QTEST_MAIN(TextureTest) +#pragma optimize("", off) +#define LOAD_TEXTURE_COUNT 40 +static const QDir TEST_DIR("D:/ktx_texture_test"); + +std::string vertexShaderSource = R"SHADER( +#line 14 +layout(location = 0) out vec2 outTexCoord0; + +const vec4 VERTICES[] = vec4[]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4( 1.0, -1.0, 0.0, 1.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4( 1.0, 1.0, 0.0, 1.0) +); + +void main() { + outTexCoord0 = VERTICES[gl_VertexID].xy; + outTexCoord0 += 1.0; + outTexCoord0 /= 2.0; + gl_Position = VERTICES[gl_VertexID]; +} +)SHADER"; + +std::string fragmentShaderSource = R"SHADER( +#line 28 + +uniform sampler2D tex; + +layout(location = 0) in vec2 inTexCoord0; +layout(location = 0) out vec4 outFragColor; + +void main() { + outFragColor = texture(tex, inTexCoord0); + outFragColor.a = 1.0; + //outFragColor.rb = inTexCoord0; +} + +)SHADER"; + +void TextureTest::initTestCase() { + getDefaultOpenGLSurfaceFormat(); + _canvas.create(); + if (!_canvas.makeCurrent()) { + qFatal("Unable to make test GL context current"); + } + gl::initModuleGl(); + gpu::Context::init(); + _gpuContext = std::make_shared(); + gpu::Texture::setAllowedGPUMemoryUsage(MB_TO_BYTES(4096)); + + _canvas.makeCurrent(); + { + auto VS = gpu::Shader::createVertex(vertexShaderSource); + auto PS = gpu::Shader::createPixel(fragmentShaderSource); + auto program = gpu::Shader::createProgram(VS, PS); + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + // If the pipeline did not exist, make it + auto state = std::make_shared(); + state->setCullMode(gpu::State::CULL_NONE); + state->setDepthTest({}); + state->setBlendFunction({ false }); + _pipeline = gpu::Pipeline::create(program, state); + } + + { _framebuffer.reset(gpu::Framebuffer::create("cached", gpu::Element::COLOR_SRGBA_32, _size.x, _size.y)); } + + { + auto entryList = TEST_DIR.entryList({ "*.ktx" }, QDir::Filter::Files); + _textureFiles.reserve(entryList.size()); + for (auto entry : entryList) { + auto textureFile = TEST_DIR.absoluteFilePath(entry).toStdString(); + _textureFiles.push_back(textureFile); + } + } + + { + std::shuffle(_textureFiles.begin(), _textureFiles.end(), std::default_random_engine()); + size_t newTextureCount = std::min(_textureFiles.size(), LOAD_TEXTURE_COUNT); + for (size_t i = 0; i < newTextureCount; ++i) { + const auto& textureFile = _textureFiles[i]; + auto texture = gpu::Texture::unserialize(textureFile); + _textures.push_back(texture); + } + } +} + +void TextureTest::cleanupTestCase() { + _gpuContext.reset(); +} + +void TextureTest::beginFrame() { + _gpuContext->recycle(); + _gpuContext->beginFrame(); + gpu::doInBatch("TestWindow::beginFrame", _gpuContext, [&](gpu::Batch& batch) { + batch.setFramebuffer(_framebuffer); + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLORS, { 0.0f, 0.1f, 0.2f, 1.0f }); + batch.clearDepthFramebuffer(1e4); + batch.setViewportTransform({ 0, 0, _size.x, _size.y }); + }); +} + +void TextureTest::endFrame() { + gpu::doInBatch("TestWindow::endFrame::finish", _gpuContext, [&](gpu::Batch& batch) { batch.resetStages(); }); + auto framePointer = _gpuContext->endFrame(); + _gpuContext->consumeFrameUpdates(framePointer); + _gpuContext->executeFrame(framePointer); + // Simulate swapbuffers with a finish + glFinish(); + QThread::msleep(10); +} + +void TextureTest::renderFrame(const std::function& renderLambda) { + beginFrame(); + gpu::doInBatch("Test::body", _gpuContext, renderLambda); + endFrame(); +} + + +inline bool afterUsecs(uint64_t& startUsecs, uint64_t maxIntervalUecs) { + auto now = usecTimestampNow(); + auto interval = now - startUsecs; + if (interval > maxIntervalUecs) { + startUsecs = now; + return true; + } + return false; +} + +inline bool afterSecs(uint64_t& startUsecs, uint64_t maxIntervalSecs) { + return afterUsecs(startUsecs, maxIntervalSecs * USECS_PER_SECOND); +} + +template +void reportEvery(uint64_t& lastReportUsecs, uint64_t secs, F lamdba) { + if (afterSecs(lastReportUsecs, secs)) { + lamdba(); + } +} + +inline void failAfter(uint64_t startUsecs, uint64_t secs, const char* message) { + if (afterSecs(startUsecs, secs)) { + qFatal(message); + } +} + +void TextureTest::testTextureLoading() { + auto renderTexturesLamdba = [this](gpu::Batch& batch) { + batch.setPipeline(_pipeline); + for (const auto& texture : _textures) { + batch.setResourceTexture(0, texture); + batch.draw(gpu::TRIANGLE_STRIP, 4, 0); + } + }; + + size_t totalSize = 0; + for (const auto& texture : _textures) { + totalSize += texture->evalTotalSize(); + } + + auto reportLambda = [=] { + qDebug() << "Expected" << totalSize; + qDebug() << "Allowed " << gpu::Texture::getAllowedGPUMemoryUsage(); + qDebug() << "Allocated " << gpu::Context::getTextureResourceGPUMemSize(); + qDebug() << "Populated " << gpu::Context::getTextureResourcePopulatedGPUMemSize(); + qDebug() << "Pending " << gpu::Context::getTexturePendingGPUTransferMemSize(); + }; + + auto lastReport = usecTimestampNow(); + auto start = usecTimestampNow(); + while (totalSize != gpu::Context::getTextureResourceGPUMemSize()) { + reportEvery(lastReport, 4, reportLambda); + failAfter(start, 10, "Failed to allocate texture memory after 10 seconds"); + renderFrame(renderTexturesLamdba); + } + + // Restart the timer + start = usecTimestampNow(); + auto allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); + auto populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); + while (allocatedMemory != populatedMemory && 0 != gpu::Context::getTexturePendingGPUTransferMemSize()) { + reportEvery(lastReport, 4, reportLambda); + failAfter(start, 10, "Failed to populate texture memory after 10 seconds"); + renderFrame(); + allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); + populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); + } + QCOMPARE(allocatedMemory, totalSize); + QCOMPARE(populatedMemory, totalSize); +} + diff --git a/tests/gpu/src/TextureTest.h b/tests/gpu/src/TextureTest.h new file mode 100644 index 0000000000..f3753f5e9b --- /dev/null +++ b/tests/gpu/src/TextureTest.h @@ -0,0 +1,37 @@ +// +// Created by Bradley Austin Davis on 2018/05/08 +// Copyright 2013-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 +// + +#pragma once + +#include +#include +#include + +class TextureTest : public QObject { + Q_OBJECT + +private: + void beginFrame(); + void endFrame(); + void renderFrame(const std::function& = [](gpu::Batch&){}); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void testTextureLoading(); + +private: + OffscreenGLCanvas _canvas; + gpu::ContextPointer _gpuContext; + gpu::PipelinePointer _pipeline; + gpu::FramebufferPointer _framebuffer; + gpu::TexturePointer _colorBuffer, _depthBuffer; + const glm::uvec2 _size{ 640, 480 }; + std::vector _textureFiles; + std::vector _textures; +}; From 7fbad47351f472c65030a59c128069eef8cf06a0 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 9 May 2018 09:52:00 -0700 Subject: [PATCH 107/152] Working on texture test --- libraries/test-utils/CMakeLists.txt | 3 + .../src/test-utils/FileDownloader.cpp | 21 +++ .../src/test-utils/FileDownloader.h | 23 +++ tests/QTestExtensions.h | 43 ++++- tests/gpu/CMakeLists.txt | 10 +- tests/gpu/src/TextureTest.cpp | 157 +++++++++++++----- tests/gpu/src/TextureTest.h | 6 +- 7 files changed, 214 insertions(+), 49 deletions(-) create mode 100644 libraries/test-utils/CMakeLists.txt create mode 100644 libraries/test-utils/src/test-utils/FileDownloader.cpp create mode 100644 libraries/test-utils/src/test-utils/FileDownloader.h diff --git a/libraries/test-utils/CMakeLists.txt b/libraries/test-utils/CMakeLists.txt new file mode 100644 index 0000000000..2c23e96c1e --- /dev/null +++ b/libraries/test-utils/CMakeLists.txt @@ -0,0 +1,3 @@ +set(TARGET_NAME test-utils) +setup_hifi_library(Network Gui) + diff --git a/libraries/test-utils/src/test-utils/FileDownloader.cpp b/libraries/test-utils/src/test-utils/FileDownloader.cpp new file mode 100644 index 0000000000..09049e3e0c --- /dev/null +++ b/libraries/test-utils/src/test-utils/FileDownloader.cpp @@ -0,0 +1,21 @@ +#include "FileDownloader.h" + +#include +#include + +FileDownloader::FileDownloader(QUrl url, const Handler& handler, QObject* parent) : QObject(parent), _handler(handler) { + connect(&_accessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileDownloaded(QNetworkReply*))); + _accessManager.get(QNetworkRequest(url)); +} + +void FileDownloader::waitForDownload() { + while (!_complete) { + QCoreApplication::processEvents(); + } +} + +void FileDownloader::fileDownloaded(QNetworkReply* pReply) { + _handler(pReply->readAll()); + pReply->deleteLater(); + _complete = true; +} diff --git a/libraries/test-utils/src/test-utils/FileDownloader.h b/libraries/test-utils/src/test-utils/FileDownloader.h new file mode 100644 index 0000000000..5a618fcf45 --- /dev/null +++ b/libraries/test-utils/src/test-utils/FileDownloader.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +class FileDownloader : public QObject { + Q_OBJECT + +public: + using Handler = std::function; + + FileDownloader(QUrl url, const Handler& handler, QObject* parent = 0); + + void waitForDownload(); + +private slots: + void fileDownloaded(QNetworkReply* pReply); + +private: + QNetworkAccessManager _accessManager; + Handler _handler; + bool _complete { false }; +}; diff --git a/tests/QTestExtensions.h b/tests/QTestExtensions.h index b7b9795a9a..c43ef3f73e 100644 --- a/tests/QTestExtensions.h +++ b/tests/QTestExtensions.h @@ -13,8 +13,9 @@ #define hifi_QTestExtensions_hpp #include +#include #include - +#include #include "GLMTestUtils.h" // Implements several extensions to QtTest. @@ -302,3 +303,43 @@ inline auto errorTest (float actual, float expected, float acceptableRelativeErr QCOMPARE_WITH_LAMBDA(actual, expected, errorTest(actual, expected, relativeError)) + +inline QString getTestResource(const QString& relativePath) { + static QDir dir; + static std::once_flag once; + std::call_once(once, []{ + QFileInfo fileInfo(__FILE__); + auto parentDir = fileInfo.absoluteDir(); + auto rootDir = parentDir.absoluteFilePath(".."); + dir = QDir::cleanPath(rootDir); + }); + + return QDir::cleanPath(dir.absoluteFilePath(relativePath)); +} + +inline bool afterUsecs(uint64_t& startUsecs, uint64_t maxIntervalUecs) { + auto now = usecTimestampNow(); + auto interval = now - startUsecs; + if (interval > maxIntervalUecs) { + startUsecs = now; + return true; + } + return false; +} + +inline bool afterSecs(uint64_t& startUsecs, uint64_t maxIntervalSecs) { + return afterUsecs(startUsecs, maxIntervalSecs * USECS_PER_SECOND); +} + +template +void reportEvery(uint64_t& lastReportUsecs, uint64_t secs, F lamdba) { + if (afterSecs(lastReportUsecs, secs)) { + lamdba(); + } +} + +inline void failAfter(uint64_t startUsecs, uint64_t secs, const char* message) { + if (afterSecs(startUsecs, secs)) { + QFAIL(message); + } +} diff --git a/tests/gpu/CMakeLists.txt b/tests/gpu/CMakeLists.txt index 6974953b40..ad0eac5822 100644 --- a/tests/gpu/CMakeLists.txt +++ b/tests/gpu/CMakeLists.txt @@ -1,9 +1,17 @@ # Declare dependencies macro (setup_testcase_dependencies) # link in the shared libraries - link_hifi_libraries(shared ktx gpu gl ${PLATFORM_GL_BACKEND}) + link_hifi_libraries(shared test-utils ktx gpu gl ${PLATFORM_GL_BACKEND}) package_libraries_for_deployment() target_opengl() + target_zlib() + find_package(QuaZip REQUIRED) + target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${QUAZIP_INCLUDE_DIRS}) + target_link_libraries(${TARGET_NAME} ${QUAZIP_LIBRARIES}) + if (WIN32) + add_paths_to_fixup_libs(${QUAZIP_DLL_PATH}) + add_dependency_external_projects(wasapi) + endif () endmacro () setup_hifi_testcase() diff --git a/tests/gpu/src/TextureTest.cpp b/tests/gpu/src/TextureTest.cpp index 9377a18244..f896914579 100644 --- a/tests/gpu/src/TextureTest.cpp +++ b/tests/gpu/src/TextureTest.cpp @@ -8,16 +8,27 @@ #include "TextureTest.h" +#include + #include #include #include #include #include +#include + +#include +#include + +#include "../../QTestExtensions.h" + +#pragma optimize("", off) QTEST_MAIN(TextureTest) -#pragma optimize("", off) + #define LOAD_TEXTURE_COUNT 40 -static const QDir TEST_DIR("D:/ktx_texture_test"); + +static const QString TEST_DATA("https://hifi-public.s3.amazonaws.com/austin/test_data/test_ktx.zip"); std::string vertexShaderSource = R"SHADER( #line 14 @@ -54,7 +65,10 @@ void main() { )SHADER"; +#define USE_SERVER_DATA 1 + void TextureTest::initTestCase() { + _resourcesPath = getTestResource("interface/resources"); getDefaultOpenGLSurfaceFormat(); _canvas.create(); if (!_canvas.makeCurrent()) { @@ -63,7 +77,32 @@ void TextureTest::initTestCase() { gl::initModuleGl(); gpu::Context::init(); _gpuContext = std::make_shared(); - gpu::Texture::setAllowedGPUMemoryUsage(MB_TO_BYTES(4096)); +#if USE_SERVER_DATA + if (!_testDataDir.isValid()) { + qFatal("Unable to create temp directory"); + } + + QString path = _testDataDir.path(); + FileDownloader(TEST_DATA, + [&](const QByteArray& data) { + QTemporaryFile zipFile; + if (zipFile.open()) { + zipFile.write(data); + zipFile.close(); + } + if (!_testDataDir.isValid()) { + qFatal("Unable to create temp dir"); + } + auto files = JlCompress::extractDir(zipFile.fileName(), _testDataDir.path()); + for (const auto& file : files) { + qDebug() << file; + } + }) + .waitForDownload(); + _resourcesPath = _testDataDir.path(); +#else + _resourcesPath = "D:/test_ktx"; +#endif _canvas.makeCurrent(); { @@ -80,19 +119,21 @@ void TextureTest::initTestCase() { _pipeline = gpu::Pipeline::create(program, state); } - { _framebuffer.reset(gpu::Framebuffer::create("cached", gpu::Element::COLOR_SRGBA_32, _size.x, _size.y)); } + _framebuffer.reset(gpu::Framebuffer::create("cached", gpu::Element::COLOR_SRGBA_32, _size.x, _size.y)); + // Find the test textures { - auto entryList = TEST_DIR.entryList({ "*.ktx" }, QDir::Filter::Files); + QDir resourcesDir(_resourcesPath); + auto entryList = resourcesDir.entryList({ "*.ktx" }, QDir::Filter::Files); _textureFiles.reserve(entryList.size()); for (auto entry : entryList) { - auto textureFile = TEST_DIR.absoluteFilePath(entry).toStdString(); + auto textureFile = resourcesDir.absoluteFilePath(entry).toStdString(); _textureFiles.push_back(textureFile); } } + // Load the test textures { - std::shuffle(_textureFiles.begin(), _textureFiles.end(), std::default_random_engine()); size_t newTextureCount = std::min(_textureFiles.size(), LOAD_TEXTURE_COUNT); for (size_t i = 0; i < newTextureCount; ++i) { const auto& textureFile = _textureFiles[i]; @@ -103,6 +144,9 @@ void TextureTest::initTestCase() { } void TextureTest::cleanupTestCase() { + _framebuffer.reset(); + _pipeline.reset(); + _gpuContext->recycle(); _gpuContext.reset(); } @@ -133,35 +177,8 @@ void TextureTest::renderFrame(const std::function& renderLamb endFrame(); } - -inline bool afterUsecs(uint64_t& startUsecs, uint64_t maxIntervalUecs) { - auto now = usecTimestampNow(); - auto interval = now - startUsecs; - if (interval > maxIntervalUecs) { - startUsecs = now; - return true; - } - return false; -} - -inline bool afterSecs(uint64_t& startUsecs, uint64_t maxIntervalSecs) { - return afterUsecs(startUsecs, maxIntervalSecs * USECS_PER_SECOND); -} - -template -void reportEvery(uint64_t& lastReportUsecs, uint64_t secs, F lamdba) { - if (afterSecs(lastReportUsecs, secs)) { - lamdba(); - } -} - -inline void failAfter(uint64_t startUsecs, uint64_t secs, const char* message) { - if (afterSecs(startUsecs, secs)) { - qFatal(message); - } -} - void TextureTest::testTextureLoading() { + QVERIFY(_textures.size() > 0); auto renderTexturesLamdba = [this](gpu::Batch& batch) { batch.setPipeline(_pipeline); for (const auto& texture : _textures) { @@ -170,39 +187,87 @@ void TextureTest::testTextureLoading() { } }; - size_t totalSize = 0; + size_t expectedAllocation = 0; for (const auto& texture : _textures) { - totalSize += texture->evalTotalSize(); + expectedAllocation += texture->evalTotalSize(); } + QVERIFY(_textures.size() > 0); auto reportLambda = [=] { - qDebug() << "Expected" << totalSize; - qDebug() << "Allowed " << gpu::Texture::getAllowedGPUMemoryUsage(); + qDebug() << "Allowed " << gpu::Texture::getAllowedGPUMemoryUsage(); qDebug() << "Allocated " << gpu::Context::getTextureResourceGPUMemSize(); qDebug() << "Populated " << gpu::Context::getTextureResourcePopulatedGPUMemSize(); qDebug() << "Pending " << gpu::Context::getTexturePendingGPUTransferMemSize(); }; + auto allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); + auto populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); + + // Cycle frames we're fully allocated + // We need to use the texture rendering lambda auto lastReport = usecTimestampNow(); auto start = usecTimestampNow(); - while (totalSize != gpu::Context::getTextureResourceGPUMemSize()) { + while (expectedAllocation != allocatedMemory) { reportEvery(lastReport, 4, reportLambda); failAfter(start, 10, "Failed to allocate texture memory after 10 seconds"); renderFrame(renderTexturesLamdba); + allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); + populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); } + QCOMPARE(allocatedMemory, expectedAllocation); // Restart the timer start = usecTimestampNow(); - auto allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); - auto populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); - while (allocatedMemory != populatedMemory && 0 != gpu::Context::getTexturePendingGPUTransferMemSize()) { + // Cycle frames we're fully populated + while (allocatedMemory != populatedMemory || 0 != gpu::Context::getTexturePendingGPUTransferMemSize()) { reportEvery(lastReport, 4, reportLambda); failAfter(start, 10, "Failed to populate texture memory after 10 seconds"); renderFrame(); allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); } - QCOMPARE(allocatedMemory, totalSize); - QCOMPARE(populatedMemory, totalSize); -} + reportLambda(); + QCOMPARE(populatedMemory, allocatedMemory); + // FIXME workaround a race condition in the difference between populated size and the actual _populatedMip value in the texture + for (size_t i = 0; i < _textures.size(); ++i) { + renderFrame(); + } + + // Test on-demand deallocation of memory + auto maxMemory = allocatedMemory / 2; + gpu::Texture::setAllowedGPUMemoryUsage(maxMemory); + + // Restart the timer + start = usecTimestampNow(); + // Cycle frames until the allocated memory is below the max memory + while (allocatedMemory > maxMemory || allocatedMemory != populatedMemory) { + reportEvery(lastReport, 4, reportLambda); + failAfter(start, 10, "Failed to deallocate texture memory after 10 seconds"); + renderFrame(renderTexturesLamdba); + allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); + populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); + } + reportLambda(); + + // Verify that the allocation is now below the target + QVERIFY(allocatedMemory <= maxMemory); + // Verify that populated memory is the same as allocated memory + QCOMPARE(populatedMemory, allocatedMemory); + + // Restart the timer + start = usecTimestampNow(); + // Reset the max memory to automatic + gpu::Texture::setAllowedGPUMemoryUsage(0); + // Cycle frames we're fully populated + while (allocatedMemory != expectedAllocation || allocatedMemory != populatedMemory) { + reportEvery(lastReport, 4, reportLambda); + failAfter(start, 10, "Failed to populate texture memory after 10 seconds"); + renderFrame(); + allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); + populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); + } + reportLambda(); + QCOMPARE(allocatedMemory, expectedAllocation); + QCOMPARE(populatedMemory, allocatedMemory); +} diff --git a/tests/gpu/src/TextureTest.h b/tests/gpu/src/TextureTest.h index f3753f5e9b..9d3dc4ab81 100644 --- a/tests/gpu/src/TextureTest.h +++ b/tests/gpu/src/TextureTest.h @@ -9,6 +9,8 @@ #pragma once #include +#include + #include #include @@ -18,7 +20,7 @@ class TextureTest : public QObject { private: void beginFrame(); void endFrame(); - void renderFrame(const std::function& = [](gpu::Batch&){}); + void renderFrame(const std::function& = [](gpu::Batch&) {}); private slots: void initTestCase(); @@ -26,6 +28,8 @@ private slots: void testTextureLoading(); private: + QString _resourcesPath; + QTemporaryDir _testDataDir; OffscreenGLCanvas _canvas; gpu::ContextPointer _gpuContext; gpu::PipelinePointer _pipeline; From 57691d5d66cafb7cf55216f96f3b32426fee3a20 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 9 May 2018 12:36:26 -0700 Subject: [PATCH 108/152] Cache downloaded assets --- tests/gpu/src/TextureTest.cpp | 54 +++++++++++++++++------------------ tests/gpu/src/TextureTest.h | 1 - 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/tests/gpu/src/TextureTest.cpp b/tests/gpu/src/TextureTest.cpp index f896914579..65d0933302 100644 --- a/tests/gpu/src/TextureTest.cpp +++ b/tests/gpu/src/TextureTest.cpp @@ -8,6 +8,7 @@ #include "TextureTest.h" +#include #include #include @@ -22,13 +23,12 @@ #include "../../QTestExtensions.h" -#pragma optimize("", off) - QTEST_MAIN(TextureTest) #define LOAD_TEXTURE_COUNT 40 static const QString TEST_DATA("https://hifi-public.s3.amazonaws.com/austin/test_data/test_ktx.zip"); +static const QString TEST_DIR_NAME("{630b8f02-52af-4cdf-a896-24e472b94b28}"); std::string vertexShaderSource = R"SHADER( #line 14 @@ -65,9 +65,18 @@ void main() { )SHADER"; -#define USE_SERVER_DATA 1 +QtMessageHandler originalHandler; + +void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { +#if defined(Q_OS_WIN) + OutputDebugStringA(message.toStdString().c_str()); + OutputDebugStringA("\n"); +#endif + originalHandler(type, context, message); +} void TextureTest::initTestCase() { + originalHandler = qInstallMessageHandler(messageHandler); _resourcesPath = getTestResource("interface/resources"); getDefaultOpenGLSurfaceFormat(); _canvas.create(); @@ -77,32 +86,21 @@ void TextureTest::initTestCase() { gl::initModuleGl(); gpu::Context::init(); _gpuContext = std::make_shared(); -#if USE_SERVER_DATA - if (!_testDataDir.isValid()) { - qFatal("Unable to create temp directory"); - } - QString path = _testDataDir.path(); - FileDownloader(TEST_DATA, - [&](const QByteArray& data) { - QTemporaryFile zipFile; - if (zipFile.open()) { - zipFile.write(data); - zipFile.close(); - } - if (!_testDataDir.isValid()) { - qFatal("Unable to create temp dir"); - } - auto files = JlCompress::extractDir(zipFile.fileName(), _testDataDir.path()); - for (const auto& file : files) { - qDebug() << file; - } - }) - .waitForDownload(); - _resourcesPath = _testDataDir.path(); -#else - _resourcesPath = "D:/test_ktx"; -#endif + _resourcesPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + TEST_DIR_NAME; + if (!QFileInfo(_resourcesPath).exists()) { + QDir(_resourcesPath).mkpath("."); + FileDownloader(TEST_DATA, + [&](const QByteArray& data) { + QTemporaryFile zipFile; + if (zipFile.open()) { + zipFile.write(data); + zipFile.close(); + } + JlCompress::extractDir(zipFile.fileName(), _resourcesPath); + }) + .waitForDownload(); + } _canvas.makeCurrent(); { diff --git a/tests/gpu/src/TextureTest.h b/tests/gpu/src/TextureTest.h index 9d3dc4ab81..91f8a358ea 100644 --- a/tests/gpu/src/TextureTest.h +++ b/tests/gpu/src/TextureTest.h @@ -29,7 +29,6 @@ private slots: private: QString _resourcesPath; - QTemporaryDir _testDataDir; OffscreenGLCanvas _canvas; gpu::ContextPointer _gpuContext; gpu::PipelinePointer _pipeline; From e0b57a22286207c86c31f24cfc4582c212d26139 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Wed, 9 May 2018 18:20:19 -0300 Subject: [PATCH 109/152] Code review in radar.js --- scripts/system/+android/radar.js | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/scripts/system/+android/radar.js b/scripts/system/+android/radar.js index 67ba896207..5d93ed4db1 100644 --- a/scripts/system/+android/radar.js +++ b/scripts/system/+android/radar.js @@ -346,9 +346,9 @@ function pinchUpdate(event) { } Camera.position = { - x: Camera.position.x, - y:radarHeight, - z:Camera.position.z + x : Camera.position.x, + y : radarHeight, + z : Camera.position.z }; if (!draggingCamera) { @@ -360,7 +360,7 @@ function pinchUpdate(event) { } function isInsideSquare(coords0, coords1, halfside) { - return coords0 != undefined && coords1!= undefined && + return coords0 != undefined && coords1 != undefined && Math.abs(coords0.x - coords1.x) <= halfside && Math.abs(coords0.y - coords1.y) <= halfside; } @@ -372,7 +372,7 @@ function dragScrollUpdate(event) { // drag management var pickRay = Camera.computePickRay(event.x, event.y); var dragAt = Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, - radarHeight-MyAvatar.position.y)); + radarHeight - MyAvatar.position.y)); if (lastDragAt === undefined || lastDragAt === null) { lastDragAt = dragAt; @@ -1082,29 +1082,20 @@ function renderAllOthersAvatarIcons() { } } -/******************************************************************************* - * Entities (to remark) cache structure for showing entities markers - ******************************************************************************/ - var ICON_ENTITY_DEFAULT_DIMENSIONS = { x : 0.10, y : 0.00001, z : 0.10 }; -var entityIconModelDimensionsVal = { - x : 0, - y : 0.00001, - z : 0 -}; + function teleportIconModelDimensions(y) { - // given the current height, give a size - // TODO: receive entity.position.y and substract to radarHeight + var teleportModelDimensions = ICON_ENTITY_DEFAULT_DIMENSIONS; var xz = -0.002831 * (radarHeight - y) + 0.1; - entityIconModelDimensionsVal.x = xz; - entityIconModelDimensionsVal.z = xz; + teleportModelDimensions.x = xz; + teleportModelDimensions.z = xz; // reuse object - return entityIconModelDimensionsVal; + return teleportModelDimensions; } /******************************************************************************* From 9b6225db40bfa1f69707e2a1507a007f2eed9b4f Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 9 May 2018 14:29:10 -0700 Subject: [PATCH 110/152] Bump default packet version 20 -> 21 --- libraries/networking/src/udt/PacketHeaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 98b0e1d892..e7a793d267 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -91,7 +91,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::Ping: return static_cast(PingVersion::IncludeConnectionID); default: - return 20; + return 21; } } From cd3836883bf4d7472bd4303b47e4a25771f8e444 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Wed, 9 May 2018 19:27:03 -0300 Subject: [PATCH 111/152] 10 seconds timeout hides name --- scripts/system/+android/displayNames.js | 26 ++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/scripts/system/+android/displayNames.js b/scripts/system/+android/displayNames.js index 8ed2b35daf..b65731f5a7 100644 --- a/scripts/system/+android/displayNames.js +++ b/scripts/system/+android/displayNames.js @@ -18,6 +18,8 @@ var METERS_ABOVE_HEAD = 0.4; var TEXT_LINE_HEIGHT = .1; var TEXT_MARGIN = 0.025; +var HIDE_MS = 10000; + var currentTouchToAnalize = null; var rayExclusionList = []; @@ -29,21 +31,31 @@ var currentlyShownAvatar = { var logEnabled = false; +var hideTimer = null; + function printd(str) { if (logEnabled) { print("[displayNames.js] " + str); } } +function clearOverlay() { + currentlyShownAvatar.avatar = null; + if (currentlyShownAvatar.overlay) { + Overlays.editOverlay(currentlyShownAvatar.overlay, {visible: false}); + } +} + function touchedAvatar(avatarID, avatarData) { printd("[AVATARNAME] touchEnd FOUND " + JSON.stringify(avatarData)); + if (hideTimer) { + Script.clearTimeout(hideTimer); + } + // Case: touching an already selected avatar if (currentlyShownAvatar.avatar && currentlyShownAvatar.avatarID == avatarID) { - currentlyShownAvatar.avatar = null; - if (currentlyShownAvatar.overlay) { - Overlays.editOverlay(currentlyShownAvatar.overlay, {visible: false}); - } + clearOverlay(); return; } @@ -77,12 +89,16 @@ function touchedAvatar(avatarID, avatarData) { x: textSize.width + 2 * TEXT_MARGIN, y: TEXT_LINE_HEIGHT + 2 * TEXT_MARGIN }, - localPosition: {x: 0, y: METERS_ABOVE_HEAD, z:0 }, + localPosition: { x: 0, y: METERS_ABOVE_HEAD, z: 0 }, text: nameToShow, parentID: avatarData.sessionUUID, parentJointIndex: avatarData.getJointIndex("Head"), visible: true }); + + hideTimer = Script.setTimeout(function() { + clearOverlay(); + }, HIDE_MS); } function touchBegin(event) { From cb336bdeab4b0400af37fdf62073566f8106bd35 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 10 May 2018 10:55:50 -0700 Subject: [PATCH 112/152] Fix linux build problems --- tests/QTestExtensions.h | 8 ++++---- tests/gpu/src/TextureTest.cpp | 21 +++++++++++++++++---- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/tests/QTestExtensions.h b/tests/QTestExtensions.h index c43ef3f73e..ac037d831b 100644 --- a/tests/QTestExtensions.h +++ b/tests/QTestExtensions.h @@ -317,7 +317,7 @@ inline QString getTestResource(const QString& relativePath) { return QDir::cleanPath(dir.absoluteFilePath(relativePath)); } -inline bool afterUsecs(uint64_t& startUsecs, uint64_t maxIntervalUecs) { +inline bool afterUsecs(quint64& startUsecs, quint64 maxIntervalUecs) { auto now = usecTimestampNow(); auto interval = now - startUsecs; if (interval > maxIntervalUecs) { @@ -327,18 +327,18 @@ inline bool afterUsecs(uint64_t& startUsecs, uint64_t maxIntervalUecs) { return false; } -inline bool afterSecs(uint64_t& startUsecs, uint64_t maxIntervalSecs) { +inline bool afterSecs(quint64& startUsecs, quint64 maxIntervalSecs) { return afterUsecs(startUsecs, maxIntervalSecs * USECS_PER_SECOND); } template -void reportEvery(uint64_t& lastReportUsecs, uint64_t secs, F lamdba) { +void doEvery(quint64& lastReportUsecs, quint64 secs, F lamdba) { if (afterSecs(lastReportUsecs, secs)) { lamdba(); } } -inline void failAfter(uint64_t startUsecs, uint64_t secs, const char* message) { +inline void failAfter(quint64 startUsecs, quint64 secs, const char* message) { if (afterSecs(startUsecs, secs)) { QFAIL(message); } diff --git a/tests/gpu/src/TextureTest.cpp b/tests/gpu/src/TextureTest.cpp index 65d0933302..18361af791 100644 --- a/tests/gpu/src/TextureTest.cpp +++ b/tests/gpu/src/TextureTest.cpp @@ -206,7 +206,7 @@ void TextureTest::testTextureLoading() { auto lastReport = usecTimestampNow(); auto start = usecTimestampNow(); while (expectedAllocation != allocatedMemory) { - reportEvery(lastReport, 4, reportLambda); + doEvery(lastReport, 4, reportLambda); failAfter(start, 10, "Failed to allocate texture memory after 10 seconds"); renderFrame(renderTexturesLamdba); allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); @@ -218,7 +218,7 @@ void TextureTest::testTextureLoading() { start = usecTimestampNow(); // Cycle frames we're fully populated while (allocatedMemory != populatedMemory || 0 != gpu::Context::getTexturePendingGPUTransferMemSize()) { - reportEvery(lastReport, 4, reportLambda); + doEvery(lastReport, 4, reportLambda); failAfter(start, 10, "Failed to populate texture memory after 10 seconds"); renderFrame(); allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); @@ -240,7 +240,7 @@ void TextureTest::testTextureLoading() { start = usecTimestampNow(); // Cycle frames until the allocated memory is below the max memory while (allocatedMemory > maxMemory || allocatedMemory != populatedMemory) { - reportEvery(lastReport, 4, reportLambda); + doEvery(lastReport, 4, reportLambda); failAfter(start, 10, "Failed to deallocate texture memory after 10 seconds"); renderFrame(renderTexturesLamdba); allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); @@ -259,7 +259,7 @@ void TextureTest::testTextureLoading() { gpu::Texture::setAllowedGPUMemoryUsage(0); // Cycle frames we're fully populated while (allocatedMemory != expectedAllocation || allocatedMemory != populatedMemory) { - reportEvery(lastReport, 4, reportLambda); + doEvery(lastReport, 4, reportLambda); failAfter(start, 10, "Failed to populate texture memory after 10 seconds"); renderFrame(); allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); @@ -268,4 +268,17 @@ void TextureTest::testTextureLoading() { reportLambda(); QCOMPARE(allocatedMemory, expectedAllocation); QCOMPARE(populatedMemory, allocatedMemory); + + _textures.clear(); + // Cycle frames we're fully populated + while (allocatedMemory != 0) { + failAfter(start, 10, "Failed to clear texture memory after 10 seconds"); + renderFrame(); + allocatedMemory = gpu::Context::getTextureResourceGPUMemSize(); + populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize(); + } + QCOMPARE(allocatedMemory, 0); + QCOMPARE(populatedMemory, 0); + qDebug() << "Done"; + } From a061e84ad7028d59dc7a8db72c070df6a9fba999 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Thu, 10 May 2018 19:40:02 +0100 Subject: [PATCH 113/152] remove unused commented code --- .../qml/dialogs/assetDialog/AssetDialogContent.qml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml index ed442aa191..914fe139ab 100644 --- a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml +++ b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml @@ -20,14 +20,8 @@ Item { // Set from OffscreenUi::assetDialog() property alias dir: assetTableModel.folder property alias filter: selectionType.filtersString - property int options // Not used. property bool selectDirectory: false - - // Not implemented. - // property bool saveDialog: false; - // property bool multiSelect: false; - property bool singleClickNavigate: false HifiConstants { id: hifi } @@ -84,7 +78,6 @@ Item { size: 28 width: height enabled: destination !== "" - // onClicked: d.navigateHome(); onClicked: assetTableModel.folder = destination; } } From c6f93a17eb93160776b70756f8d7106accaab143 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Thu, 10 May 2018 18:01:50 -0300 Subject: [PATCH 114/152] Fix freeze when quitting the app trough back button --- .../hifiinterface/HomeActivity.java | 5 ++++- .../hifiinterface/PermissionChecker.java | 1 - .../qt5/android/bindings/QtActivity.java | 21 +++++++++++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 803483d724..5476460b38 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -25,6 +25,8 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; +import org.qtproject.qt5.android.bindings.QtActivity; + import io.highfidelity.hifiinterface.view.DomainAdapter; public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @@ -234,7 +236,8 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On } @Override public void onBackPressed() { - finishAffinity(); + QtActivity.forceQuit(); + finish(); } public void onSearchClear(View view) { diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/PermissionChecker.java b/android/app/src/main/java/io/highfidelity/hifiinterface/PermissionChecker.java index 2b48d85a48..45060d6d0c 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/PermissionChecker.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/PermissionChecker.java @@ -63,7 +63,6 @@ public class PermissionChecker extends Activity { } private void launchActivityWithPermissions(){ - finish(); Intent i = new Intent(this, InterfaceActivity.class); startActivity(i); finish(); diff --git a/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java b/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java index 0639c66f38..517008cf9a 100644 --- a/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java @@ -69,6 +69,9 @@ public class QtActivity extends Activity { private QtActivityLoader m_loader = new QtActivityLoader(this); public boolean isLoading; + private boolean forcedQuit; + + public static QtActivity instance; public QtActivity() { } @@ -237,6 +240,7 @@ public class QtActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); onCreateHook(savedInstanceState); + instance = this; } //--------------------------------------------------------------------------- @@ -362,6 +366,7 @@ public class QtActivity extends Activity { protected void onDestroy() { super.onDestroy(); QtApplication.invokeDelegate(); + instance = null; } //--------------------------------------------------------------------------- @@ -504,7 +509,7 @@ public class QtActivity extends Activity { // GC: this trick allow us to show a splash activity until Qt app finishes // loading if (!isLoading) { - //QtApplication.invokeDelegate(); + QtApplication.invokeDelegate(); } } //--------------------------------------------------------------------------- @@ -638,14 +643,26 @@ public class QtActivity extends Activity { protected void onStart() { super.onStart(); QtApplication.invokeDelegate(); + if (forcedQuit) { + finish(); + } } //--------------------------------------------------------------------------- @Override protected void onStop() { super.onStop(); - //QtApplication.invokeDelegate(); + if (forcedQuit) { + QtApplication.invokeDelegate(); + } } + + public static void forceQuit() { + if (instance != null) { + instance.forcedQuit = true; + } + } + //--------------------------------------------------------------------------- @Override From f30908fb26f4a22aa2cc8ad004ea44c5e6341d3e Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Thu, 10 May 2018 18:21:33 -0300 Subject: [PATCH 115/152] Android - Remove delay starting Home + Change default joystick flag --- .../java/io/highfidelity/hifiinterface/SplashActivity.java | 7 ++----- libraries/ui/src/VirtualPadManager.h | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java index 08f8615a16..4e32578158 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java @@ -27,10 +27,7 @@ public class SplashActivity extends Activity { } public void onAppLoadedComplete() { - // Give interface more time so textures don't fail(got deleted) on Adreno (joystick) - new Handler(getMainLooper()).postDelayed(() -> { - startActivity(new Intent(this, HomeActivity.class)); - new Handler(getMainLooper()).postDelayed(() -> SplashActivity.this.finish(), 1000); - }, 500); + startActivity(new Intent(this, HomeActivity.class)); + SplashActivity.this.finish(); } } diff --git a/libraries/ui/src/VirtualPadManager.h b/libraries/ui/src/VirtualPadManager.h index 6f7fbcc921..cfd40a6447 100644 --- a/libraries/ui/src/VirtualPadManager.h +++ b/libraries/ui/src/VirtualPadManager.h @@ -58,7 +58,7 @@ namespace VirtualPad { private: Instance _leftVPadInstance; - bool _enabled; + bool _enabled {true}; bool _hidden; glm::vec2 _jumpButtonPosition; int _extraBottomMargin {0}; From 32d10641dc44861e9c22b3505cc579ce02648845 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 10 May 2018 14:41:35 -0700 Subject: [PATCH 116/152] don't enable so much logging when 'verbose logging' is turned on --- interface/src/Application.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 20efe73f08..6810621093 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2253,8 +2253,12 @@ void Application::updateVerboseLogging() { } bool enable = menu->isOptionChecked(MenuOption::VerboseLogging); - QString rules = "*.debug=%1\n" - "*.info=%1"; + QString rules = + "hifi.*.debug=%1\n" + "hifi.*.info=%1\n" + "hifi.audio-stream.warning=false\n" + "hifi.audio-stream.debug=false\n" + "hifi.audio-stream.info=false"; rules = rules.arg(enable ? "true" : "false"); QLoggingCategory::setFilterRules(rules); } From fab85c3f6d433940d7c503d3a103317447300593 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 11 May 2018 09:52:48 +1200 Subject: [PATCH 117/152] Fix JSDoc function definitions specifying properties instead of params --- .../entities/src/EntityScriptingInterface.h | 4 +- .../src/AssetScriptingInterface.h | 58 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 8adb5138f2..7e47d9e2d4 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -481,8 +481,8 @@ public slots: /**jsdoc * Gets the status of server entity script attached to an entity * @function Entities.getServerScriptStatus - * @property {Uuid} entityID - The ID of the entity to get the server entity script status for. - * @property {Entities~getServerScriptStatusCallback} callback - The function to call upon completion. + * @param {Uuid} entityID - The ID of the entity to get the server entity script status for. + * @param {Entities~getServerScriptStatusCallback} callback - The function to call upon completion. * @returns {boolean} true always. */ /**jsdoc diff --git a/libraries/script-engine/src/AssetScriptingInterface.h b/libraries/script-engine/src/AssetScriptingInterface.h index eb9a628ae3..7f7a3a68b0 100644 --- a/libraries/script-engine/src/AssetScriptingInterface.h +++ b/libraries/script-engine/src/AssetScriptingInterface.h @@ -186,36 +186,36 @@ public: /**jsdoc * @function Assets.deleteAsset - * @property {} options - * @property {} scope - * @property {} [callback = ""] + * @param {} options + * @param {} scope + * @param {} [callback = ""] */ Q_INVOKABLE void deleteAsset(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); /**jsdoc * @function Assets.resolveAsset - * @property {} options - * @property {} scope - * @property {} [callback = ""] + * @param {} options + * @param {} scope + * @param {} [callback = ""] */ Q_INVOKABLE void resolveAsset(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); /**jsdoc * @function Assets.decompressData - * @property {} options - * @property {} scope - * @property {} [callback = ""] + * @param {} options + * @param {} scope + * @param {} [callback = ""] */ Q_INVOKABLE void decompressData(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); /**jsdoc * @function Assets.compressData - * @property {} options - * @property {} scope - * @property {} [callback = ""] + * @param {} options + * @param {} scope + * @param {} [callback = ""] */ Q_INVOKABLE void compressData(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); @@ -229,7 +229,7 @@ public: /**jsdoc * @function Assets.canWriteCacheValue - * @property {string} url + * @param {string} url * @returns {boolean} */ @@ -237,8 +237,8 @@ public: /**jsdoc * @function Assets.getCacheStatus - * @property {} scope - * @property {} [callback=undefined] + * @param {} scope + * @param {} [callback=undefined] */ Q_INVOKABLE void getCacheStatus(QScriptValue scope, QScriptValue callback = QScriptValue()) { @@ -247,38 +247,38 @@ public: /**jsdoc * @function Assets.queryCacheMeta - * @property {} options - * @property {} scope - * @property {} [callback=undefined] + * @param {} options + * @param {} scope + * @param {} [callback=undefined] */ Q_INVOKABLE void queryCacheMeta(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); /**jsdoc * @function Assets.loadFromCache - * @property {} options - * @property {} scope - * @property {} [callback=undefined] + * @param {} options + * @param {} scope + * @param {} [callback=undefined] */ Q_INVOKABLE void loadFromCache(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); /**jsdoc * @function Assets.saveToCache - * @property {} options - * @property {} scope - * @property {} [callback=undefined] + * @param {} options + * @param {} scope + * @param {} [callback=undefined] */ Q_INVOKABLE void saveToCache(QScriptValue options, QScriptValue scope, QScriptValue callback = QScriptValue()); /**jsdoc * @function Assets.saveToCache - * @property {} url - * @property {} data - * @property {} metadata - * @property {} scope - * @property {} [callback=undefined] + * @param {} url + * @param {} data + * @param {} metadata + * @param {} scope + * @param {} [callback=undefined] */ Q_INVOKABLE void saveToCache(const QUrl& url, const QByteArray& data, const QVariantMap& metadata, From 29355ba8fb9974bcb2d521584f43e5555db03233 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 25 Apr 2018 10:25:34 +0200 Subject: [PATCH 118/152] Fixed procedural shaders (cherry picked from commit eab7dd60067ff18bab4a3c2f7d7b6c618bcf2945) --- libraries/render-utils/src/simple.slf | 10 ++++++++++ libraries/render-utils/src/simple_fade.slf | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index ed77777184..338f8607ee 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -16,7 +16,17 @@ // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; +in vec4 _positionES; + +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index 6e7aee2894..1cb4127e7b 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -19,9 +19,19 @@ // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; +in vec4 _positionES; in vec4 _positionWS; +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES + //PROCEDURAL_COMMON_BLOCK #line 1001 From ec439086a2f67c791f76f6c0258c1de4886997ca Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 25 Apr 2018 18:56:18 +0200 Subject: [PATCH 119/152] Extended to other shaders (cherry picked from commit 328f1dec9be27258b154130f51681ece09b76c97) --- libraries/render-utils/src/forward_simple.slf | 10 ++++++++++ .../render-utils/src/forward_simple_transparent.slf | 9 +++++++++ libraries/render-utils/src/simple.slf | 8 ++++---- libraries/render-utils/src/simple_fade.slf | 8 ++++---- libraries/render-utils/src/simple_transparent.slf | 10 ++++++++++ 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/libraries/render-utils/src/forward_simple.slf b/libraries/render-utils/src/forward_simple.slf index 587fcbde73..1ac44750a7 100644 --- a/libraries/render-utils/src/forward_simple.slf +++ b/libraries/render-utils/src/forward_simple.slf @@ -16,11 +16,21 @@ <@include ForwardGlobalLight.slh@> <$declareEvalSkyboxGlobalColor()$> + // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; in vec4 _positionES; +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES + layout(location = 0) out vec4 _fragColor0; //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/forward_simple_transparent.slf b/libraries/render-utils/src/forward_simple_transparent.slf index f40ba2ed4f..8be2759571 100644 --- a/libraries/render-utils/src/forward_simple_transparent.slf +++ b/libraries/render-utils/src/forward_simple_transparent.slf @@ -18,9 +18,18 @@ // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; in vec4 _positionES; +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES + layout(location = 0) out vec4 _fragColor0; //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 338f8607ee..7591dc1882 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -23,10 +23,10 @@ in vec4 _positionMS; in vec4 _positionES; // For retro-compatibility -#define _normal _normalWS -#define _modelNormal _normalMS -#define _position _positionMS -#define _eyePosition _positionES +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index 1cb4127e7b..0710c3e10b 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -27,10 +27,10 @@ in vec4 _positionES; in vec4 _positionWS; // For retro-compatibility -#define _normal _normalWS -#define _modelNormal _normalMS -#define _position _positionMS -#define _eyePosition _positionES +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES //PROCEDURAL_COMMON_BLOCK diff --git a/libraries/render-utils/src/simple_transparent.slf b/libraries/render-utils/src/simple_transparent.slf index c9815e8a80..ee79d2c0c4 100644 --- a/libraries/render-utils/src/simple_transparent.slf +++ b/libraries/render-utils/src/simple_transparent.slf @@ -16,7 +16,17 @@ // the interpolated normal in vec3 _normalWS; +in vec3 _normalMS; in vec4 _color; +in vec2 _texCoord0; +in vec4 _positionMS; +in vec4 _positionES; + +// For retro-compatibility +#define _normal _normalWS +#define _modelNormal _normalMS +#define _position _positionMS +#define _eyePosition _positionES //PROCEDURAL_COMMON_BLOCK From 826c427e2a0d12bfd2e72dc166a7e66b6db33c61 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 10 May 2018 15:42:59 -0700 Subject: [PATCH 120/152] trying to sort-out audio-stream logging --- interface/src/Application.cpp | 1 - libraries/audio/src/AudioLogging.cpp | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6810621093..ff8b545c57 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2256,7 +2256,6 @@ void Application::updateVerboseLogging() { QString rules = "hifi.*.debug=%1\n" "hifi.*.info=%1\n" - "hifi.audio-stream.warning=false\n" "hifi.audio-stream.debug=false\n" "hifi.audio-stream.info=false"; rules = rules.arg(enable ? "true" : "false"); diff --git a/libraries/audio/src/AudioLogging.cpp b/libraries/audio/src/AudioLogging.cpp index 8a668a4bcb..73091885cb 100644 --- a/libraries/audio/src/AudioLogging.cpp +++ b/libraries/audio/src/AudioLogging.cpp @@ -12,5 +12,4 @@ #include "AudioLogging.h" Q_LOGGING_CATEGORY(audio, "hifi.audio") -Q_LOGGING_CATEGORY(audiostream, "hifi.audio-stream", QtWarningMsg) - +Q_LOGGING_CATEGORY(audiostream, "hifi.audio-stream") From 50a53a5174bd3dc2a29131d0e316266c060a5d66 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 10 May 2018 16:00:01 -0700 Subject: [PATCH 121/152] fix lastEdited vs pal --- scripts/system/pal.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 0a01007ee9..84328001e1 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -251,6 +251,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See }); } break; + case 'refresh': // old name for refreshNearby case 'refreshNearby': data = {}; ExtendedOverlay.some(function (overlay) { // capture the audio data @@ -743,10 +744,13 @@ function receiveMessage(channel, messageString, senderID) { var message = JSON.parse(messageString); switch (message.method) { case 'select': - sendToQml(message); // Accepts objects, not just strings. + if (!onPalScreen) { + tablet.loadQMLSource(PAL_QML_SOURCE); + Script.setTimeout(function () { sendToQml(message); }, 1000); + } else { + sendToQml(message); // Accepts objects, not just strings. + } break; - default: - print('Unrecognized PAL message', messageString); } } From bf26aec260fe661b2391d1a92157c80c5c29b6cc Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 10 May 2018 16:39:56 -0700 Subject: [PATCH 122/152] untabify --- scripts/system/pal.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 84328001e1..c70c2729f5 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -744,12 +744,12 @@ function receiveMessage(channel, messageString, senderID) { var message = JSON.parse(messageString); switch (message.method) { case 'select': - if (!onPalScreen) { - tablet.loadQMLSource(PAL_QML_SOURCE); - Script.setTimeout(function () { sendToQml(message); }, 1000); - } else { + if (!onPalScreen) { + tablet.loadQMLSource(PAL_QML_SOURCE); + Script.setTimeout(function () { sendToQml(message); }, 1000); + } else { sendToQml(message); // Accepts objects, not just strings. - } + } break; } } From 0ac12fa3177cb77a31cf9590b992b788e6c11586 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 10 May 2018 17:56:54 -0700 Subject: [PATCH 123/152] Bug fix for Vive Tracker Calibration Settings This issue was inadvertently introduced by the name change of the Vive display plugin. --- interface/resources/qml/hifi/tablet/ControllerSettings.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/tablet/ControllerSettings.qml b/interface/resources/qml/hifi/tablet/ControllerSettings.qml index ffd3d81b84..0beb28977e 100644 --- a/interface/resources/qml/hifi/tablet/ControllerSettings.qml +++ b/interface/resources/qml/hifi/tablet/ControllerSettings.qml @@ -172,7 +172,7 @@ StackView { source: InputConfiguration.configurationLayout(box.currentText); onLoaded: { if (loader.item.hasOwnProperty("pluginName")) { - if (box.currentText === "Vive") { + if (box.currentText === "HTC Vive") { loader.item.pluginName = "OpenVR"; } else { loader.item.pluginName = box.currentText; From 1364f4391d1ce0400a3ab1e16d1754f99f7793d4 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 10 May 2018 18:02:44 -0700 Subject: [PATCH 124/152] Can store JSON object. --- interface/src/Application.cpp | 29 ++++++++++++------- interface/src/Application.h | 3 +- .../src/scripting/TestScriptingInterface.cpp | 27 +++++++++++++++++ .../src/scripting/TestScriptingInterface.h | 5 ++++ 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 20efe73f08..89cbf0f6c0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -734,9 +734,9 @@ extern InputPluginList getInputPlugins(); extern void saveInputPluginSettings(const InputPluginList& plugins); // Parameters used for running tests from teh command line -const QString TEST_SCRIPT_COMMAND { "--testScript" }; -const QString TEST_QUIT_WHEN_FINISHED_OPTION { "quitWhenFinished" }; -const QString TEST_SNAPSHOT_LOCATION_COMMAND { "--testSnapshotLocation" }; +const QString TEST_SCRIPT_COMMAND{ "--testScript" }; +const QString TEST_QUIT_WHEN_FINISHED_OPTION{ "quitWhenFinished" }; +const QString TEST_RESULTS_LOCATION_COMMAND{ "--testResultsLocation" }; bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { const char** constArgv = const_cast(argv); @@ -1014,22 +1014,25 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // If the URL scheme is http(s) or ftp, then use as is, else - treat it as a local file // This is done so as not break previous command line scripts - if (testScriptPath.left(URL_SCHEME_HTTP.length()) == URL_SCHEME_HTTP || testScriptPath.left(URL_SCHEME_FTP.length()) == URL_SCHEME_FTP) { + if (testScriptPath.left(URL_SCHEME_HTTP.length()) == URL_SCHEME_HTTP || + testScriptPath.left(URL_SCHEME_FTP.length()) == URL_SCHEME_FTP) { + setProperty(hifi::properties::TEST, QUrl::fromUserInput(testScriptPath)); } else if (QFileInfo(testScriptPath).exists()) { setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); } - // quite when finished parameter must directly follow the test script + // quite when finished parameter must directly follow the test script if ((i + 2) < args.size() && args.at(i + 2) == TEST_QUIT_WHEN_FINISHED_OPTION) { quitWhenFinished = true; } - } else if (args.at(i) == TEST_SNAPSHOT_LOCATION_COMMAND) { + } else if (args.at(i) == TEST_RESULTS_LOCATION_COMMAND) { // Set test snapshot location only if it is a writeable directory - QString pathname(args.at(i + 1)); - QFileInfo fileInfo(pathname); + QString path(args.at(i + 1)); + + QFileInfo fileInfo(path); if (fileInfo.isDir() && fileInfo.isWritable()) { - testSnapshotLocation = pathname; + testResultsLocation = path; } } } @@ -7475,7 +7478,9 @@ void Application::loadAvatarBrowser() const { void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) { postLambdaEvent([notify, includeAnimated, aspectRatio, filename, this] { // Get a screenshot and save it - QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, testSnapshotLocation); + QString path = + Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, testResultsLocation); + // If we're not doing an animated snapshot as well... if (!includeAnimated) { // Tell the dependency manager that the capture of the still snapshot has taken place. @@ -7489,7 +7494,9 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa void Application::takeSecondaryCameraSnapshot(const QString& filename) { postLambdaEvent([filename, this] { - QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename, testSnapshotLocation); + QString snapshotPath = + Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename, testResultsLocation); + emit DependencyManager::get()->stillSnapshotTaken(snapshotPath, true); }); } diff --git a/interface/src/Application.h b/interface/src/Application.h index aa6469c592..3189b87775 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -418,6 +418,7 @@ public slots: void updateVerboseLogging(); Q_INVOKABLE void openAndroidActivity(const QString& activityName); + QString getTestResultsLocation() { return testResultsLocation; }; private slots: void onDesktopRootItemCreated(QQuickItem* qmlContext); @@ -751,7 +752,7 @@ private: std::atomic _pendingIdleEvent { true }; std::atomic _pendingRenderEvent { true }; - QString testSnapshotLocation; + QString testResultsLocation; bool quitWhenFinished { false }; }; #endif // hifi_Application_h diff --git a/interface/src/scripting/TestScriptingInterface.cpp b/interface/src/scripting/TestScriptingInterface.cpp index 9e7c0e142e..15a024fa03 100644 --- a/interface/src/scripting/TestScriptingInterface.cpp +++ b/interface/src/scripting/TestScriptingInterface.cpp @@ -160,3 +160,30 @@ void TestScriptingInterface::clearCaches() { qApp->reloadResourceCaches(); } +// Writes a JSON object from javascript to a file +void TestScriptingInterface::saveObject(QVariant variant, const QString& filename) { + QString testResultsLocation = qApp->getTestResultsLocation(); + if (testResultsLocation.isNull()) { + return; + } + + QJsonDocument jsonDocument; + jsonDocument = QJsonDocument::fromVariant(variant); + if (jsonDocument.isNull()) { + return; + } + + QByteArray jsonData = jsonDocument.toJson(); + + // Append trailing slash if needed + if (testResultsLocation.right(1) != "/") { + testResultsLocation += "/"; + } + + QString filepath = QDir::cleanPath(testResultsLocation + filename); + QFile file(filepath); + + file.open(QFile::WriteOnly); + file.write(jsonData); + file.close(); +} diff --git a/interface/src/scripting/TestScriptingInterface.h b/interface/src/scripting/TestScriptingInterface.h index 687cb41689..4b469244d1 100644 --- a/interface/src/scripting/TestScriptingInterface.h +++ b/interface/src/scripting/TestScriptingInterface.h @@ -83,6 +83,11 @@ public slots: */ void clearCaches(); + /**jsdoc + * Save a JSON object to a file in the test results location + */ + void saveObject(QVariant v, const QString& filename); + private: bool waitForCondition(qint64 maxWaitMs, std::function condition); }; From de4a2ca3b26c30e3eea4a9e75a155ad34da1c917 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 10 May 2018 18:44:53 -0700 Subject: [PATCH 125/152] update procedural skybox on user data change --- .../entities-renderer/src/RenderableZoneEntityItem.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 5a3caa55fe..5062162b6e 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -251,7 +251,7 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen updateAmbientLightFromEntity(entity); } - if (skyboxChanged) { + if (skyboxChanged || _proceduralUserData != entity->getUserData()) { updateKeyBackgroundFromEntity(entity); } @@ -295,6 +295,10 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint return true; } + if (entity->getUserData() != _proceduralUserData) { + return true; + } + #if 0 if (_typedEntity->getCompoundShapeURL() != _lastShapeURL) { return true; From 9e462e777cd027db0b3d277eefde709b370da1e7 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Fri, 11 May 2018 11:01:24 +0200 Subject: [PATCH 126/152] Fixed compilation error with transparent procedurals --- .../procedural/src/procedural/Procedural.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index c155d5bd7f..259da163dd 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -270,18 +270,24 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm // Leave this here for debugging // qCDebug(procedural) << "FragmentShader:\n" << fragmentShaderSource.c_str(); + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("iChannel0"), 0)); + slotBindings.insert(gpu::Shader::Binding(std::string("iChannel1"), 1)); + slotBindings.insert(gpu::Shader::Binding(std::string("iChannel2"), 2)); + slotBindings.insert(gpu::Shader::Binding(std::string("iChannel3"), 3)); + _opaqueFragmentShader = gpu::Shader::createPixel(opaqueShaderSource); _opaqueShader = gpu::Shader::createProgram(_vertexShader, _opaqueFragmentShader); - _transparentFragmentShader = gpu::Shader::createPixel(transparentShaderSource); - _transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader); + gpu::Shader::makeProgram(*_opaqueShader, slotBindings); - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("iChannel0"), 0)); - slotBindings.insert(gpu::Shader::Binding(std::string("iChannel1"), 1)); - slotBindings.insert(gpu::Shader::Binding(std::string("iChannel2"), 2)); - slotBindings.insert(gpu::Shader::Binding(std::string("iChannel3"), 3)); - gpu::Shader::makeProgram(*_opaqueShader, slotBindings); - gpu::Shader::makeProgram(*_transparentShader, slotBindings); + if (!transparentShaderSource.empty() && transparentShaderSource != opaqueShaderSource) { + _transparentFragmentShader = gpu::Shader::createPixel(transparentShaderSource); + _transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader); + gpu::Shader::makeProgram(*_transparentShader, slotBindings); + } else { + _transparentFragmentShader = _opaqueFragmentShader; + _transparentShader = _opaqueShader; + } _opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState); _transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState); From ff88911f93ef0df2d0ae8f9a7cd2bdcf780c4753 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Fri, 11 May 2018 12:26:03 +0200 Subject: [PATCH 127/152] Protected procedural skyboxes from NaNs and negative values returned by procedural shader --- libraries/graphics/src/graphics/skybox.slf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/graphics/src/graphics/skybox.slf b/libraries/graphics/src/graphics/skybox.slf index 7b25e36af7..153e73b9ef 100755 --- a/libraries/graphics/src/graphics/skybox.slf +++ b/libraries/graphics/src/graphics/skybox.slf @@ -35,8 +35,11 @@ void main(void) { #ifdef PROCEDURAL vec3 color = getSkyboxColor(); - // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline - color = pow(color, vec3(2.2)); + // Protect from NaNs and negative values + color = mix(color, vec3(0), isnan(color)); + color = max(color, vec3(0)); + // Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline + color = pow(color, vec3(2.2)); _fragColor = vec4(color, 0.0); // FIXME: scribe does not yet scrub out else statements From 4eba727849e4294625e31bdec2a8312b2c1445fd Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 11 May 2018 10:47:41 -0700 Subject: [PATCH 128/152] fix qml crash on start up --- .../resources/qml/dialogs/assetDialog/AssetDialogContent.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml index 31e013638e..c3e842bc2f 100644 --- a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml +++ b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml @@ -21,6 +21,7 @@ Item { // Set from OffscreenUi::assetDialog() property alias dir: assetTableModel.folder property alias filter: selectionType.filtersString + property int options property bool selectDirectory: false property bool singleClickNavigate: false From db460e985619e29a93e20f8e15d4761a214998c2 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Fri, 11 May 2018 16:09:40 -0300 Subject: [PATCH 129/152] Put back the worker thread for account manager in android --- .../hifiinterface/HomeActivity.java | 1 - .../qt5/android/bindings/QtActivity.java | 18 +----------------- interface/src/AndroidHelper.cpp | 8 ++++++++ interface/src/AndroidHelper.h | 3 +++ interface/src/Application.cpp | 5 +++++ 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index 5476460b38..b403aba84e 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -236,7 +236,6 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On } @Override public void onBackPressed() { - QtActivity.forceQuit(); finish(); } diff --git a/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java b/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java index 517008cf9a..9fcaea6153 100644 --- a/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/android/app/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java @@ -69,9 +69,6 @@ public class QtActivity extends Activity { private QtActivityLoader m_loader = new QtActivityLoader(this); public boolean isLoading; - private boolean forcedQuit; - - public static QtActivity instance; public QtActivity() { } @@ -240,7 +237,6 @@ public class QtActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); onCreateHook(savedInstanceState); - instance = this; } //--------------------------------------------------------------------------- @@ -366,7 +362,6 @@ public class QtActivity extends Activity { protected void onDestroy() { super.onDestroy(); QtApplication.invokeDelegate(); - instance = null; } //--------------------------------------------------------------------------- @@ -643,24 +638,13 @@ public class QtActivity extends Activity { protected void onStart() { super.onStart(); QtApplication.invokeDelegate(); - if (forcedQuit) { - finish(); - } } //--------------------------------------------------------------------------- @Override protected void onStop() { super.onStop(); - if (forcedQuit) { - QtApplication.invokeDelegate(); - } - } - - public static void forceQuit() { - if (instance != null) { - instance.forcedQuit = true; - } + QtApplication.invokeDelegate(); } //--------------------------------------------------------------------------- diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp index dd2c344620..fad4468622 100644 --- a/interface/src/AndroidHelper.cpp +++ b/interface/src/AndroidHelper.cpp @@ -10,11 +10,19 @@ // #include "AndroidHelper.h" #include +#include AndroidHelper::AndroidHelper() { + workerThread.start(); } AndroidHelper::~AndroidHelper() { + workerThread.quit(); + workerThread.wait(); +} + +void AndroidHelper::init() { + DependencyManager::get()->moveToThread(&workerThread); } void AndroidHelper::requestActivity(const QString &activityName) { diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h index 019db9c4a7..0c6d05cbb2 100644 --- a/interface/src/AndroidHelper.h +++ b/interface/src/AndroidHelper.h @@ -13,6 +13,7 @@ #define hifi_Android_Helper_h #include +#include class AndroidHelper : public QObject { Q_OBJECT @@ -21,6 +22,7 @@ public: static AndroidHelper instance; return instance; } + void init(); void requestActivity(const QString &activityName); void notifyLoadComplete(); void goBackFromAndroidActivity(); @@ -35,6 +37,7 @@ signals: private: AndroidHelper(); ~AndroidHelper(); + QThread workerThread; }; #endif \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5f9bafdf65..2852cb38c8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -850,7 +850,11 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); +#if defined(Q_OS_ANDROID) + DependencyManager::set(); // use the default user agent getter +#else DependencyManager::set(std::bind(&Application::getUserAgent, qApp)); +#endif DependencyManager::set(); DependencyManager::set(ScriptEngine::CLIENT_SCRIPT); DependencyManager::set(); @@ -2246,6 +2250,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); #if defined(Q_OS_ANDROID) + AndroidHelper::instance().init(); AndroidHelper::instance().notifyLoadComplete(); #endif } From 85a6e2555fcec45ce812fd898088913b1e206089 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 11 May 2018 13:55:29 -0700 Subject: [PATCH 130/152] don't assert when unserializing a 'spring' action --- libraries/physics/src/ObjectActionTractor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/ObjectActionTractor.cpp b/libraries/physics/src/ObjectActionTractor.cpp index a48989be33..4235bbd616 100644 --- a/libraries/physics/src/ObjectActionTractor.cpp +++ b/libraries/physics/src/ObjectActionTractor.cpp @@ -397,7 +397,7 @@ void ObjectActionTractor::deserialize(QByteArray serializedArguments) { EntityDynamicType type; dataStream >> type; - assert(type == getType()); + assert(type == getType() || type == DYNAMIC_TYPE_SPRING); QUuid id; dataStream >> id; From 9b5da09dc731f449eac429d712a88477b39c3920 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Fri, 11 May 2018 18:08:56 -0300 Subject: [PATCH 131/152] Fix connection issue syncing two AccountManagers --- android/app/src/main/cpp/native.cpp | 8 ++++---- interface/src/AndroidHelper.cpp | 16 ++++++++++++++-- interface/src/AndroidHelper.h | 3 +++ libraries/networking/src/AccountManager.cpp | 14 ++++++++++++++ libraries/networking/src/AccountManager.h | 1 + 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp index de2f6ec3e0..9a5d29d675 100644 --- a/android/app/src/main/cpp/native.cpp +++ b/android/app/src/main/cpp/native.cpp @@ -218,7 +218,7 @@ Java_io_highfidelity_hifiinterface_LoginActivity_nativeLogin(JNIEnv *env, jobjec env->ReleaseStringUTFChars(username_, c_username); env->ReleaseStringUTFChars(password_, c_password); - auto accountManager = DependencyManager::get(); + auto accountManager = AndroidHelper::instance().getAccountManager(); __loginActivity = QAndroidJniObject(instance); @@ -253,18 +253,18 @@ Java_io_highfidelity_hifiinterface_SplashActivity_registerLoadCompleteListener(J } JNIEXPORT jboolean JNICALL Java_io_highfidelity_hifiinterface_HomeActivity_nativeIsLoggedIn(JNIEnv *env, jobject instance) { - return DependencyManager::get()->isLoggedIn(); + return AndroidHelper::instance().getAccountManager()->isLoggedIn(); } JNIEXPORT void JNICALL Java_io_highfidelity_hifiinterface_HomeActivity_nativeLogout(JNIEnv *env, jobject instance) { - DependencyManager::get()->logout(); + AndroidHelper::instance().getAccountManager()->logout(); } JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_HomeActivity_nativeGetDisplayName(JNIEnv *env, jobject instance) { - QString username = DependencyManager::get()->getAccountInfo().getUsername(); + QString username = AndroidHelper::instance().getAccountManager()->getAccountInfo().getUsername(); return env->NewStringUTF(username.toLatin1().data()); } diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp index fad4468622..825a45c21b 100644 --- a/interface/src/AndroidHelper.cpp +++ b/interface/src/AndroidHelper.cpp @@ -13,7 +13,6 @@ #include AndroidHelper::AndroidHelper() { - workerThread.start(); } AndroidHelper::~AndroidHelper() { @@ -22,7 +21,20 @@ AndroidHelper::~AndroidHelper() { } void AndroidHelper::init() { - DependencyManager::get()->moveToThread(&workerThread); + workerThread.start(); + _accountManager = QSharedPointer(new AccountManager, &QObject::deleteLater); + _accountManager->setIsAgent(true); + _accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL()); + _accountManager->setSessionID(DependencyManager::get()->getSessionID()); + connect(_accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) { + DependencyManager::get()->setAccountInfo(AndroidHelper::instance().getAccountManager()->getAccountInfo()); + DependencyManager::get()->setAuthURL(authURL); + }); + + connect(_accountManager.data(), &AccountManager::logoutComplete, [] () { + DependencyManager::get()->logout(); + }); + _accountManager->moveToThread(&workerThread); } void AndroidHelper::requestActivity(const QString &activityName) { diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h index 0c6d05cbb2..c5e15a31da 100644 --- a/interface/src/AndroidHelper.h +++ b/interface/src/AndroidHelper.h @@ -14,6 +14,7 @@ #include #include +#include class AndroidHelper : public QObject { Q_OBJECT @@ -26,6 +27,7 @@ public: void requestActivity(const QString &activityName); void notifyLoadComplete(); void goBackFromAndroidActivity(); + QSharedPointer getAccountManager() { return _accountManager; } AndroidHelper(AndroidHelper const&) = delete; void operator=(AndroidHelper const&) = delete; @@ -37,6 +39,7 @@ signals: private: AndroidHelper(); ~AndroidHelper(); + QSharedPointer _accountManager; QThread workerThread; }; diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 049129b2ba..e70e3e26d0 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -453,6 +453,20 @@ void AccountManager::removeAccountFromFile() { << "from settings file."; } +void AccountManager::setAccountInfo(const DataServerAccountInfo &newAccountInfo) { + _accountInfo = newAccountInfo; + _pendingPrivateKey.clear(); + if (_isAgent && !_accountInfo.getAccessToken().token.isEmpty() && !_accountInfo.hasProfile()) { + // we are missing profile information, request it now + requestProfile(); + } + + // prepare to refresh our token if it is about to expire + if (needsToRefreshToken()) { + refreshAccessToken(); + } +} + bool AccountManager::hasValidAccessToken() { if (_accountInfo.getAccessToken().token.isEmpty() || _accountInfo.getAccessToken().isExpired()) { diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 87b17d00d5..88ebaf5656 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -88,6 +88,7 @@ public: void requestProfile(); DataServerAccountInfo& getAccountInfo() { return _accountInfo; } + void setAccountInfo(const DataServerAccountInfo &newAccountInfo); static QJsonObject dataObjectFromResponse(QNetworkReply& requestReply); From 0f8c666647619608379ff3dae398c083f2655cbf Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Fri, 11 May 2018 19:50:00 -0300 Subject: [PATCH 132/152] Trying to fix virtualpad textures corruption --- .../hifiinterface/HomeActivity.java | 2 +- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 122 +++++++++--------- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java index b403aba84e..62e487f8b7 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HomeActivity.java @@ -236,7 +236,7 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On } @Override public void onBackPressed() { - finish(); + finishAffinity(); } public void onSearchClear(View view) { diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 7c27fab591..b5a3d94a67 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -28,82 +28,82 @@ void Basic2DWindowOpenGLDisplayPlugin::customizeContext() { qreal dpi = getFullscreenTarget()->physicalDotsPerInch(); _virtualPadPixelSize = dpi * VirtualPad::Manager::BASE_DIAMETER_PIXELS / VirtualPad::Manager::DPI; - if (!_virtualPadStickTexture) { - auto iconPath = PathUtils::resourcesPath() + "images/analog_stick.png"; - auto image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); + auto iconPath = PathUtils::resourcesPath() + "images/analog_stick.png"; + auto image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); - _virtualPadStickTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadStickTexture->setSource("virtualPad stick"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadStickTexture->setUsage(usage.build()); - _virtualPadStickTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadStickTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadStickTexture->setAutoGenerateMips(true); - } + _virtualPadStickTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadStickTexture->setSource("virtualPad stick"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadStickTexture->setUsage(usage.build()); + _virtualPadStickTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadStickTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadStickTexture->setAutoGenerateMips(true); } - if (!_virtualPadStickBaseTexture) { - auto iconPath = PathUtils::resourcesPath() + "images/analog_stick_base.png"; - auto image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); - _virtualPadStickBaseTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadStickBaseTexture->setSource("virtualPad base"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadStickBaseTexture->setUsage(usage.build()); - _virtualPadStickBaseTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadStickBaseTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadStickBaseTexture->setAutoGenerateMips(true); - } + iconPath = PathUtils::resourcesPath() + "images/analog_stick_base.png"; + image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); + + _virtualPadStickBaseTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadStickBaseTexture->setSource("virtualPad base"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadStickBaseTexture->setUsage(usage.build()); + _virtualPadStickBaseTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadStickBaseTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadStickBaseTexture->setAutoGenerateMips(true); } _virtualPadJumpBtnPixelSize = dpi * VirtualPad::Manager::JUMP_BTN_FULL_PIXELS / VirtualPad::Manager::DPI; - if (!_virtualPadJumpBtnTexture) { - auto iconPath = PathUtils::resourcesPath() + "images/fly.png"; - auto image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadJumpBtnPixelSize, _virtualPadJumpBtnPixelSize, Qt::KeepAspectRatio); - image = image.mirrored(); + iconPath = PathUtils::resourcesPath() + "images/fly.png"; + image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadJumpBtnPixelSize, _virtualPadJumpBtnPixelSize, Qt::KeepAspectRatio); + image = image.mirrored(); - _virtualPadJumpBtnTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadJumpBtnTexture->setSource("virtualPad jump"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadJumpBtnTexture->setUsage(usage.build()); - _virtualPadJumpBtnTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadJumpBtnTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadJumpBtnTexture->setAutoGenerateMips(true); - } + _virtualPadJumpBtnTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadJumpBtnTexture->setSource("virtualPad jump"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadJumpBtnTexture->setUsage(usage.build()); + _virtualPadJumpBtnTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadJumpBtnTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadJumpBtnTexture->setAutoGenerateMips(true); } #endif Parent::customizeContext(); } void Basic2DWindowOpenGLDisplayPlugin::uncustomizeContext() { +#if defined(Q_OS_ANDROID) + _virtualPadStickTexture.reset(); + _virtualPadStickBaseTexture.reset(); + _virtualPadJumpBtnTexture.reset(); +#endif Parent::uncustomizeContext(); } From f97155b6cdb36fe22b6311226d5f6ed51060c704 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 11 May 2018 20:34:43 -0300 Subject: [PATCH 133/152] Revert virtualpad code. It works on Pixel XL --- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 122 +++++++++--------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index b5a3d94a67..7c27fab591 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -28,82 +28,82 @@ void Basic2DWindowOpenGLDisplayPlugin::customizeContext() { qreal dpi = getFullscreenTarget()->physicalDotsPerInch(); _virtualPadPixelSize = dpi * VirtualPad::Manager::BASE_DIAMETER_PIXELS / VirtualPad::Manager::DPI; - auto iconPath = PathUtils::resourcesPath() + "images/analog_stick.png"; - auto image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); + if (!_virtualPadStickTexture) { + auto iconPath = PathUtils::resourcesPath() + "images/analog_stick.png"; + auto image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); - _virtualPadStickTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadStickTexture->setSource("virtualPad stick"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadStickTexture->setUsage(usage.build()); - _virtualPadStickTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadStickTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadStickTexture->setAutoGenerateMips(true); + _virtualPadStickTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadStickTexture->setSource("virtualPad stick"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadStickTexture->setUsage(usage.build()); + _virtualPadStickTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadStickTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadStickTexture->setAutoGenerateMips(true); + } } + if (!_virtualPadStickBaseTexture) { + auto iconPath = PathUtils::resourcesPath() + "images/analog_stick_base.png"; + auto image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); - iconPath = PathUtils::resourcesPath() + "images/analog_stick_base.png"; - image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); - - _virtualPadStickBaseTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadStickBaseTexture->setSource("virtualPad base"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadStickBaseTexture->setUsage(usage.build()); - _virtualPadStickBaseTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadStickBaseTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadStickBaseTexture->setAutoGenerateMips(true); + _virtualPadStickBaseTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadStickBaseTexture->setSource("virtualPad base"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadStickBaseTexture->setUsage(usage.build()); + _virtualPadStickBaseTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadStickBaseTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadStickBaseTexture->setAutoGenerateMips(true); + } } _virtualPadJumpBtnPixelSize = dpi * VirtualPad::Manager::JUMP_BTN_FULL_PIXELS / VirtualPad::Manager::DPI; - iconPath = PathUtils::resourcesPath() + "images/fly.png"; - image = QImage(iconPath); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - if ((image.width() > 0) && (image.height() > 0)) { - image = image.scaled(_virtualPadJumpBtnPixelSize, _virtualPadJumpBtnPixelSize, Qt::KeepAspectRatio); - image = image.mirrored(); + if (!_virtualPadJumpBtnTexture) { + auto iconPath = PathUtils::resourcesPath() + "images/fly.png"; + auto image = QImage(iconPath); + if (image.format() != QImage::Format_ARGB32) { + image = image.convertToFormat(QImage::Format_ARGB32); + } + if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadJumpBtnPixelSize, _virtualPadJumpBtnPixelSize, Qt::KeepAspectRatio); + image = image.mirrored(); - _virtualPadJumpBtnTexture = gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Texture::MAX_NUM_MIPS, - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); - _virtualPadJumpBtnTexture->setSource("virtualPad jump"); - auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); - _virtualPadJumpBtnTexture->setUsage(usage.build()); - _virtualPadJumpBtnTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); - _virtualPadJumpBtnTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _virtualPadJumpBtnTexture->setAutoGenerateMips(true); + _virtualPadJumpBtnTexture = gpu::Texture::createStrict( + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); + _virtualPadJumpBtnTexture->setSource("virtualPad jump"); + auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); + _virtualPadJumpBtnTexture->setUsage(usage.build()); + _virtualPadJumpBtnTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _virtualPadJumpBtnTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + _virtualPadJumpBtnTexture->setAutoGenerateMips(true); + } } #endif Parent::customizeContext(); } void Basic2DWindowOpenGLDisplayPlugin::uncustomizeContext() { -#if defined(Q_OS_ANDROID) - _virtualPadStickTexture.reset(); - _virtualPadStickBaseTexture.reset(); - _virtualPadJumpBtnTexture.reset(); -#endif Parent::uncustomizeContext(); } From 898dec29cbb48dd59a0303aa52d04ba37b2e5473 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 11 May 2018 17:04:40 -0700 Subject: [PATCH 134/152] don't cache value of getControllerJointIndex at startup, because the script may run before the data is available. Instead, refresh the data every few seconds --- .../controllerModules/equipEntity.js | 12 ++--- .../controllerModules/nearActionGrabEntity.js | 2 +- .../nearGrabHyperLinkEntity.js | 8 +--- .../controllerModules/nearParentGrabEntity.js | 13 ++---- .../nearParentGrabOverlay.js | 3 +- .../controllers/controllerModules/teleport.js | 2 +- .../libraries/controllerDispatcherUtils.js | 45 ++++++++++++------- 7 files changed, 44 insertions(+), 41 deletions(-) diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 1fce772ec8..093a8b57d8 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -6,11 +6,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, - getControllerJointIndex, enableDispatcherModule, disableDispatcherModule, +/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, Camera, + getControllerJointIndex, enableDispatcherModule, disableDispatcherModule, entityIsFarGrabbedByOther, Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions, Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable, - cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE, Uuid, unhighlightTargetEntity + cloneEntity, DISPATCHER_PROPERTIES, Uuid, unhighlightTargetEntity, isInEditMode */ Script.include("/~/system/libraries/Xform.js"); @@ -781,7 +781,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } } }; - + var clearGrabActions = function(entityID) { var actionIDs = Entities.getActionIDs(entityID); var myGrabTag = "grab-" + MyAvatar.sessionUUID; @@ -794,7 +794,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } } }; - + var onMousePress = function(event) { if (isInEditMode() || !event.isLeftButton) { // don't consider any left clicks on the entity while in edit return; @@ -808,7 +808,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa if (hasEquipData && entityProperties.parentID === EMPTY_PARENT_ID && !entityIsFarGrabbedByOther(entityID)) { entityProperties.id = entityID; var rightHandPosition = MyAvatar.getJointPosition("RightHand"); - var leftHandPosition = MyAvatar.getJointPosition("LeftHand"); + var leftHandPosition = MyAvatar.getJointPosition("LeftHand"); var distanceToRightHand = Vec3.distance(entityProperties.position, rightHandPosition); var distanceToLeftHand = Vec3.distance(entityProperties.position, leftHandPosition); var leftHandAvailable = leftEquipEntity.targetEntityID === null; diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index a4e439fe2f..274a4264cd 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -10,7 +10,7 @@ propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable, Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues, TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity, - HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, unhighlightTargetEntity + HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, unhighlightTargetEntity, Uuid */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); diff --git a/scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js b/scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js index 59ce79cfd1..962ae89bb9 100644 --- a/scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js +++ b/scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js @@ -7,12 +7,8 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, - getControllerJointIndex, getGrabbableData, enableDispatcherModule, disableDispatcherModule, - propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable, - Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues, - TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity, - HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, AddressManager +/* global Script, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, + makeDispatcherModuleParameters, makeRunningValues, TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, BUMPER_ON_VALUE, AddressManager */ (function() { diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index d454d20a02..cf3a9cf14b 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -11,8 +11,7 @@ TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS, findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME, - TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Selection, DISPATCHER_HOVERING_LIST, Uuid, - highlightTargetEntity, unhighlightTargetEntity + TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -43,11 +42,6 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); [], 100); - - // XXX does handJointIndex change if the avatar changes? - this.handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"); - this.controllerJointIndex = getControllerJointIndex(this.hand); - this.thisHandIsParent = function(props) { if (!props) { return false; @@ -62,8 +56,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); return true; } - var controllerJointIndex = this.controllerJointIndex; - if (props.parentJointIndex === controllerJointIndex) { + if (props.parentJointIndex === getControllerJointIndex(this.hand)) { return true; } @@ -102,7 +95,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); // } else { // handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"); // } - handJointIndex = this.controllerJointIndex; + handJointIndex = getControllerJointIndex(this.hand); var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(targetProps.id, "startNearGrab", args); diff --git a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js index 0f876816b3..368d5c483b 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js @@ -9,7 +9,7 @@ /* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex, enableDispatcherModule, disableDispatcherModule, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, makeDispatcherModuleParameters, Overlays, makeRunningValues, Vec3, resizeTablet, getTabletWidthFromSettings, - NEAR_GRAB_RADIUS + NEAR_GRAB_RADIUS, HMD, Uuid */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -37,7 +37,6 @@ Script.include("/~/system/libraries/utils.js"); // XXX does handJointIndex change if the avatar changes? this.handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"); - this.controllerJointIndex = getControllerJointIndex(this.hand); this.getOtherModule = function() { return (this.hand === RIGHT_HAND) ? leftNearParentingGrabOverlay : rightNearParentingGrabOverlay; diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 560da57b20..3bf99ca26a 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -10,7 +10,7 @@ /* jslint bitwise: true */ -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex, +/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Vec3, HMD, Uuid, AvatarList, Picks, Pointers, PickType */ diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index 71dc5e4273..04ae01bad6 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -7,7 +7,7 @@ /* global module, Camera, HMD, MyAvatar, controllerDispatcherPlugins:true, Quat, Vec3, Overlays, Xform, - Selection, + Selection, Uuid, MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, FORBIDDEN_GRAB_TYPES:true, HAPTIC_PULSE_STRENGTH:true, HAPTIC_PULSE_DURATION:true, ZERO_VEC:true, ONE_VEC:true, DEFAULT_REGISTRATION_POINT:true, INCHES_TO_METERS:true, @@ -34,11 +34,12 @@ getGrabbableData:true, entityIsGrabbable:true, entityIsDistanceGrabbable:true, + getControllerJointIndexCacheTime:true, + getControllerJointIndexCache:true, getControllerJointIndex:true, propsArePhysical:true, controllerDispatcherPluginsNeedSort:true, projectOntoXYPlane:true, - getChildrenProps:true, projectOntoEntityXYPlane:true, projectOntoOverlayXYPlane:true, makeLaserLockInfo:true, @@ -53,6 +54,8 @@ TEAR_AWAY_COUNT:true, TEAR_AWAY_CHECK_TIME:true, distanceBetweenPointAndEntityBoundingBox:true, + entityIsEquipped:true, + entityIsFarGrabbedByOther:true, highlightTargetEntity:true, clearHighlightedEntities:true, unhighlightTargetEntity:true @@ -265,20 +268,32 @@ entityIsDistanceGrabbable = function(props) { return true; }; -getControllerJointIndex = function (hand) { - if (HMD.isHandControllerAvailable()) { - var controllerJointIndex = -1; - if (Camera.mode === "first person") { - controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ? - "_CONTROLLER_RIGHTHAND" : - "_CONTROLLER_LEFTHAND"); - } else if (Camera.mode === "third person") { - controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ? - "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : - "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"); - } +getControllerJointIndexCacheTime = [0, 0]; +getControllerJointIndexCache = [-1, -1]; - return controllerJointIndex; +getControllerJointIndex = function (hand) { + var GET_CONTROLLERJOINTINDEX_CACHE_REFRESH_TIME = 3000; // msecs + + var now = Date.now(); + if (now - getControllerJointIndexCacheTime[hand] > GET_CONTROLLERJOINTINDEX_CACHE_REFRESH_TIME) { + if (HMD.isHandControllerAvailable()) { + var controllerJointIndex = -1; + if (Camera.mode === "first person") { + controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ? + "_CONTROLLER_RIGHTHAND" : + "_CONTROLLER_LEFTHAND"); + } else if (Camera.mode === "third person") { + controllerJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ? + "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : + "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"); + } + + getControllerJointIndexCacheTime[hand] = now; + getControllerJointIndexCache[hand] = controllerJointIndex; + return controllerJointIndex; + } + } else { + return getControllerJointIndexCache[hand]; } return -1; From d39f7f7a581de8449babda0c589cd467f5cc0c0f Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 11 May 2018 21:27:42 -0300 Subject: [PATCH 135/152] Simplified avatar touch code + Fix Typo + Add my avatar to the exclusion list + Explain mouse events --- scripts/system/+android/displayNames.js | 40 ++++++++----------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/scripts/system/+android/displayNames.js b/scripts/system/+android/displayNames.js index b65731f5a7..2e2e6938ad 100644 --- a/scripts/system/+android/displayNames.js +++ b/scripts/system/+android/displayNames.js @@ -20,8 +20,8 @@ var TEXT_MARGIN = 0.025; var HIDE_MS = 10000; -var currentTouchToAnalize = null; -var rayExclusionList = []; +var currentTouchToAnalyze = null; +var rayExclusionList = []; // Updated at sessionUUID changes var currentlyShownAvatar = { avatarID: null, @@ -102,47 +102,26 @@ function touchedAvatar(avatarID, avatarData) { } function touchBegin(event) { - var pickRay = Camera.computePickRay(event.x, event.y); - var avatarRay = AvatarManager.findRayIntersection(pickRay, [], rayExclusionList); - if (avatarRay.intersects) { - currentTouchToAnalize = { - touchBegin: event, - avatarRay: avatarRay - }; - printd("[AVATARNAME] touchBegin intersection " + JSON.stringify(currentTouchToAnalize)); - } else { - printd("[AVATARNAME] touchBegin no intersection"); - } + currentTouchToAnalyze = event; } function touchEnd(event) { - if (!currentTouchToAnalize) { - printd("[AVATARNAME] touchEnd no current touch"); - currentTouchToAnalize = null; - return; - } - - // manage touches only if begin an end do: - // - touch/release the same avatar - // - minimal distance (so no apparent movent was intended but a touch/click) - // - (hold or short click don't matter) - - if (Vec3.distance({x: event.x, y: event.y }, {x: currentTouchToAnalize.touchBegin.x, y: currentTouchToAnalize.touchBegin.y}) > MAX_DISTANCE_PX) { + if (Vec3.distance({x: event.x, y: event.y }, {x: currentTouchToAnalyze.x, y: currentTouchToAnalyze.y}) > MAX_DISTANCE_PX) { printd("[AVATARNAME] touchEnd moved too much"); - currentTouchToAnalize = null; + currentTouchToAnalyze = null; return; } var pickRay = Camera.computePickRay(event.x, event.y); var avatarRay = AvatarManager.findRayIntersection(pickRay, [], rayExclusionList); - if (avatarRay.intersects && avatarRay.avatarID == currentTouchToAnalize.avatarRay.avatarID) { + if (avatarRay.intersects) { touchedAvatar(avatarRay.avatarID, AvatarManager.getAvatar(avatarRay.avatarID)); } else { printd("[AVATARNAME] touchEnd released outside the avatar"); } - currentTouchToAnalize = null; + currentTouchToAnalyze = null; } function ending() { @@ -169,6 +148,11 @@ function init() { Script.scriptEnding.connect(function () { ending(); }); + + rayExclusionList = [MyAvatar.sessionUUID]; + MyAvatar.sessionUUIDChanged.connect(function() { + rayExclusionList = [MyAvatar.sessionUUID]; + }); } init(); From 9e9e1092d69c6c55c4bb77fdf349e3d934dbf7c3 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 11 May 2018 21:37:28 -0300 Subject: [PATCH 136/152] Add Opaques tasks into RenderForwardTask --- libraries/render-utils/src/RenderForwardTask.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index c45e1dd4eb..b49735a53f 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -23,7 +23,6 @@ #include -#include "AntialiasingEffect.h" #include "StencilMaskPass.h" #include "ZoneRenderer.h" #include "FadeEffect.h" @@ -56,7 +55,7 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE]; // const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT]; const auto& metas = items.get0()[RenderFetchCullSortTask::META]; - // const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE]; + const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE]; const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE]; //const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND]; @@ -64,8 +63,6 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend fadeEffect->build(task, opaques); - const auto jitter = task.addJob("JitterCam"); - // Prepare objects shared by several jobs const auto deferredFrameTransform = task.addJob("DeferredFrameTransform"); const auto lightingModel = task.addJob("LightingModel"); @@ -82,14 +79,14 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend task.addJob("PrepareStencil", framebuffer); // Layered Overlays - //const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT); + const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT); const auto filteredOverlaysTransparent = task.addJob("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT); - //const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN(0); + const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN(0); const auto overlaysInFrontTransparent = filteredOverlaysTransparent.getN(0); - //const auto overlayInFrontOpaquesInputs = DrawOverlay3D::Inputs(overlaysInFrontOpaque, lightingModel, jitter).asVarying(); - const auto overlayInFrontTransparentsInputs = DrawOverlay3D::Inputs(overlaysInFrontTransparent, lightingModel, jitter).asVarying(); - //task.addJob("DrawOverlayInFrontOpaque", overlayInFrontOpaquesInputs, true); + const auto overlayInFrontOpaquesInputs = DrawOverlay3D::Inputs(overlaysInFrontOpaque, lightingModel, nullptr).asVarying(); + const auto overlayInFrontTransparentsInputs = DrawOverlay3D::Inputs(overlaysInFrontTransparent, lightingModel, nullptr).asVarying(); + task.addJob("DrawOverlayInFrontOpaque", overlayInFrontOpaquesInputs, true); task.addJob("DrawOverlayInFrontTransparent", overlayInFrontTransparentsInputs, false); // Draw opaques forward From 3fd8a02375595cc6177a3027f66ec83220435e9a Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 11 May 2018 21:58:12 -0300 Subject: [PATCH 137/152] Prevent this name implementation to appear in radar mode --- scripts/system/+android/displayNames.js | 17 +++++++++++++---- scripts/system/+android/modes.js | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/scripts/system/+android/displayNames.js b/scripts/system/+android/displayNames.js index 2e2e6938ad..1e9735d205 100644 --- a/scripts/system/+android/displayNames.js +++ b/scripts/system/+android/displayNames.js @@ -124,6 +124,10 @@ function touchEnd(event) { currentTouchToAnalyze = null; } +function excludeMyAvatar() { + rayExclusionList = [MyAvatar.sessionUUID]; +} + function ending() { Controller.touchBeginEvent.disconnect(touchBegin); Controller.touchEndEvent.disconnect(touchEnd); @@ -137,6 +141,8 @@ function ending() { if (currentlyShownAvatar.avatar) { currentlyShownAvatar.avatar = null; } + + MyAvatar.sessionUUIDChanged.disconnect(excludeMyAvatar); } function init() { @@ -150,11 +156,14 @@ function init() { }); rayExclusionList = [MyAvatar.sessionUUID]; - MyAvatar.sessionUUIDChanged.connect(function() { - rayExclusionList = [MyAvatar.sessionUUID]; - }); + MyAvatar.sessionUUIDChanged.connect(excludeMyAvatar); } -init(); +module.exports = { + init: init, + ending: ending +} + +//init(); // Enable to use in desktop as a standalone }()); // END LOCAL_SCOPE \ No newline at end of file diff --git a/scripts/system/+android/modes.js b/scripts/system/+android/modes.js index 0b6e98541d..2c155ae386 100644 --- a/scripts/system/+android/modes.js +++ b/scripts/system/+android/modes.js @@ -88,8 +88,10 @@ function switchToMode(newMode) { if (currentMode == MODE_RADAR) { radar.startRadarMode(); + displayNames.ending(); } else if (currentMode == MODE_MY_VIEW) { // nothing to do yet + displayNames.init(); } else { printd("Unknown view mode " + currentMode); } From aaa6038d282d9362ee3f50347d8520449ec84ee3 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Fri, 11 May 2018 22:27:58 -0300 Subject: [PATCH 138/152] Prevent calling ending on displayNames if was never started --- scripts/system/+android/displayNames.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/system/+android/displayNames.js b/scripts/system/+android/displayNames.js index 1e9735d205..9f226f5ce0 100644 --- a/scripts/system/+android/displayNames.js +++ b/scripts/system/+android/displayNames.js @@ -128,7 +128,13 @@ function excludeMyAvatar() { rayExclusionList = [MyAvatar.sessionUUID]; } +var runAtLeastOnce = false; + function ending() { + if (!runAtLeastOnce) { + return; + } + Controller.touchBeginEvent.disconnect(touchBegin); Controller.touchEndEvent.disconnect(touchEnd); Controller.mousePressEvent.disconnect(touchBegin); @@ -157,6 +163,8 @@ function init() { rayExclusionList = [MyAvatar.sessionUUID]; MyAvatar.sessionUUIDChanged.connect(excludeMyAvatar); + + runAtLeastOnce = true; } module.exports = { From a9a783588bae2dca4f048fd257253f4cca9dfe71 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 14 May 2018 09:25:17 -0700 Subject: [PATCH 139/152] Fixed typo. --- tools/auto-tester/src/Test.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index c7ce5f8893..0fb957d309 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -89,7 +89,7 @@ private: const int NUM_DIGITS { 5 }; const QString EXPECTED_IMAGE_PREFIX { "ExpectedImage_" }; - // We have to directories to work with. + // We have two directories to work with. // The first is the directory containing the test we are working with // The second contains the snapshots taken for test runs that need to be evaluated QString testDirectory; From 81ebb681bb185ff5ec5430e981333425b79f7be8 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 14 May 2018 09:35:34 -0700 Subject: [PATCH 140/152] Show invalidated items in My Purchases --- .../resources/qml/hifi/commerce/purchases/Purchases.qml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index d79b8d09fa..0b95f26f55 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -995,10 +995,6 @@ Rectangle { for (var i = 0; i < purchasesModel.count; i++) { if (purchasesModel.get(i).title.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) { - if (!purchasesModel.get(i).valid) { - continue; - } - if (purchasesModel.get(i).status !== "confirmed" && !root.isShowingMyItems) { tempPurchasesModel.insert(0, purchasesModel.get(i)); } else if ((root.isShowingMyItems && purchasesModel.get(i).edition_number === "0") || @@ -1055,10 +1051,6 @@ Rectangle { var currentId; for (var i = 0; i < tempPurchasesModel.count; i++) { currentId = tempPurchasesModel.get(i).id; - - if (!purchasesModel.get(i).valid) { - continue; - } filteredPurchasesModel.append(tempPurchasesModel.get(i)); filteredPurchasesModel.setProperty(i, 'cardBackVisible', false); filteredPurchasesModel.setProperty(i, 'isInstalled', ((root.installedApps).indexOf(currentId) > -1)); From 2a1c2ba7b1ce7fe3e583117f4d2a3c2f18f0f2d4 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 14 May 2018 09:54:05 -0700 Subject: [PATCH 141/152] PurchasedItem logic --- .../resources/qml/hifi/commerce/purchases/PurchasedItem.qml | 5 ++++- .../resources/qml/hifi/commerce/purchases/Purchases.qml | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index 4db98091c1..17c42d1b08 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -49,6 +49,7 @@ Item { property string upgradeTitle; property bool updateAvailable: root.upgradeUrl !== "" && !root.isShowingMyItems; property bool isShowingMyItems; + property bool valid; property string originalStatusText; property string originalStatusColor; @@ -239,6 +240,7 @@ Item { width: 62; onLoaded: { + item.enabled = root.valid; item.buttonGlyphText = hifi.glyphs.gift; item.buttonText = "Gift"; item.buttonClicked = function() { @@ -646,7 +648,8 @@ Item { height: 40; enabled: root.hasPermissionToRezThis && root.purchaseStatus !== "invalidated" && - MyAvatar.skeletonModelURL !== root.itemHref; + MyAvatar.skeletonModelURL !== root.itemHref && + root.valid; onHoveredChanged: { if (hovered) { diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 0b95f26f55..8fe1ebe6c9 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -616,6 +616,7 @@ Rectangle { upgradeTitle: model.upgrade_title; itemType: model.itemType; isShowingMyItems: root.isShowingMyItems; + valid: model.valid; anchors.topMargin: 10; anchors.bottomMargin: 10; From 97a493d113314016a5f4508ba09780cf122fbe47 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Mon, 14 May 2018 14:41:31 -0300 Subject: [PATCH 142/152] Android - Delay workaround to avoid joystick/controls issues --- .../java/io/highfidelity/hifiinterface/SplashActivity.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java index 4e32578158..08f8615a16 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java @@ -27,7 +27,10 @@ public class SplashActivity extends Activity { } public void onAppLoadedComplete() { - startActivity(new Intent(this, HomeActivity.class)); - SplashActivity.this.finish(); + // Give interface more time so textures don't fail(got deleted) on Adreno (joystick) + new Handler(getMainLooper()).postDelayed(() -> { + startActivity(new Intent(this, HomeActivity.class)); + new Handler(getMainLooper()).postDelayed(() -> SplashActivity.this.finish(), 1000); + }, 500); } } From e7abf3c7be64cf53ce6b167a9b74f02456f82f2e Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Mon, 14 May 2018 15:26:57 -0300 Subject: [PATCH 143/152] Android - Display Names - Use my avatar uuid directly when finding ray intersection --- scripts/system/+android/displayNames.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/scripts/system/+android/displayNames.js b/scripts/system/+android/displayNames.js index 9f226f5ce0..509d85cd2b 100644 --- a/scripts/system/+android/displayNames.js +++ b/scripts/system/+android/displayNames.js @@ -21,7 +21,6 @@ var TEXT_MARGIN = 0.025; var HIDE_MS = 10000; var currentTouchToAnalyze = null; -var rayExclusionList = []; // Updated at sessionUUID changes var currentlyShownAvatar = { avatarID: null, @@ -113,7 +112,7 @@ function touchEnd(event) { } var pickRay = Camera.computePickRay(event.x, event.y); - var avatarRay = AvatarManager.findRayIntersection(pickRay, [], rayExclusionList); + var avatarRay = AvatarManager.findRayIntersection(pickRay, [], [MyAvatar.sessionUUID]) if (avatarRay.intersects) { touchedAvatar(avatarRay.avatarID, AvatarManager.getAvatar(avatarRay.avatarID)); @@ -124,10 +123,6 @@ function touchEnd(event) { currentTouchToAnalyze = null; } -function excludeMyAvatar() { - rayExclusionList = [MyAvatar.sessionUUID]; -} - var runAtLeastOnce = false; function ending() { @@ -147,8 +142,6 @@ function ending() { if (currentlyShownAvatar.avatar) { currentlyShownAvatar.avatar = null; } - - MyAvatar.sessionUUIDChanged.disconnect(excludeMyAvatar); } function init() { @@ -161,9 +154,6 @@ function init() { ending(); }); - rayExclusionList = [MyAvatar.sessionUUID]; - MyAvatar.sessionUUIDChanged.connect(excludeMyAvatar); - runAtLeastOnce = true; } From ac78e145853a66e2dac0522144e623c7d7782c7d Mon Sep 17 00:00:00 2001 From: David Back Date: Mon, 14 May 2018 11:44:25 -0700 Subject: [PATCH 144/152] fix unequipping with capital U --- scripts/system/controllers/controllerModules/equipEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 1fce772ec8..dff1f45258 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -828,7 +828,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa }; var onKeyPress = function(event) { - if (event.text === UNEQUIP_KEY) { + if (event.text.toLowerCase() === UNEQUIP_KEY) { if (rightEquipEntity.targetEntityID) { rightEquipEntity.endEquipEntity(); } From a881d07e59f72e7de90f19478f011f0aa0c10fe3 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 14 May 2018 13:12:58 -0700 Subject: [PATCH 145/152] MS15090: Fix gifting when running marketplaces.js separately --- scripts/system/marketplaces/marketplaces.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index c3edee264f..dc4d5aa844 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -19,6 +19,7 @@ var selectionDisplay = null; // for gridTool.js to ignore Script.include("/~/system/libraries/WebTablet.js"); Script.include("/~/system/libraries/gridTool.js"); + Script.include("/~/system/libraries/connectionUtils.js"); var METAVERSE_SERVER_URL = Account.metaverseServerURL; var MARKETPLACE_URL = METAVERSE_SERVER_URL + "/marketplace"; From 83cae5460101cae5f8f5c3c76d3e76a24790ce3a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 14 May 2018 13:34:20 -0700 Subject: [PATCH 146/152] Show 'invalidated' label for valid = false --- .../hifi/commerce/purchases/PurchasedItem.qml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index 17c42d1b08..19b57354dc 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -465,7 +465,7 @@ Item { Item { id: statusContainer; - visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.numberSold > -1; + visible: root.purchaseStatus === "pending" || !root.valid || root.numberSold > -1; anchors.left: itemName.left; anchors.right: itemName.right; anchors.top: itemName.bottom; @@ -482,7 +482,7 @@ Item { text: { if (root.purchaseStatus === "pending") { "PENDING..." - } else if (root.purchaseStatus === "invalidated") { + } else if (!root.valid) { "INVALIDATED" } else if (root.numberSold > -1) { ("Sales: " + root.numberSold + "/" + (root.limitedRun === -1 ? "\u221e" : root.limitedRun)) @@ -494,7 +494,7 @@ Item { color: { if (root.purchaseStatus === "pending") { hifi.colors.blueAccent - } else if (root.purchaseStatus === "invalidated") { + } else if (!root.valid) { hifi.colors.redAccent } else { hifi.colors.baseGray @@ -508,7 +508,7 @@ Item { text: { if (root.purchaseStatus === "pending") { hifi.glyphs.question - } else if (root.purchaseStatus === "invalidated") { + } else if (!root.valid) { hifi.glyphs.question } else { "" @@ -525,7 +525,7 @@ Item { color: { if (root.purchaseStatus === "pending") { hifi.colors.blueAccent - } else if (root.purchaseStatus === "invalidated") { + } else if (!root.valid) { hifi.colors.redAccent } else { hifi.colors.baseGray @@ -540,7 +540,7 @@ Item { onClicked: { if (root.purchaseStatus === "pending") { sendToPurchases({method: 'showPendingLightbox'}); - } else if (root.purchaseStatus === "invalidated") { + } else if (!root.valid) { sendToPurchases({method: 'showInvalidatedLightbox'}); } } @@ -548,7 +548,7 @@ Item { if (root.purchaseStatus === "pending") { statusText.color = hifi.colors.blueHighlight; statusIcon.color = hifi.colors.blueHighlight; - } else if (root.purchaseStatus === "invalidated") { + } else if (!root.valid) { statusText.color = hifi.colors.redAccent; statusIcon.color = hifi.colors.redAccent; } @@ -557,7 +557,7 @@ Item { if (root.purchaseStatus === "pending") { statusText.color = hifi.colors.blueAccent; statusIcon.color = hifi.colors.blueAccent; - } else if (root.purchaseStatus === "invalidated") { + } else if (!root.valid) { statusText.color = hifi.colors.redHighlight; statusIcon.color = hifi.colors.redHighlight; } @@ -647,7 +647,6 @@ Item { width: 160; height: 40; enabled: root.hasPermissionToRezThis && - root.purchaseStatus !== "invalidated" && MyAvatar.skeletonModelURL !== root.itemHref && root.valid; From ed726c9d77ae8e218cc51e99add5e79fbcabb1a9 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 14 May 2018 13:51:13 -0700 Subject: [PATCH 147/152] OpenVR: Remove reference to HMD Standing Mode menu item This menu item has not existed for over a year. I was sometimes seeing a crash on startup when the display plugin attempted to reference this menu item. --- interface/src/Menu.h | 1 - plugins/openvr/src/OpenVrDisplayPlugin.cpp | 3 --- 2 files changed, 4 deletions(-) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 20375a71b2..be3dd705f7 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -193,7 +193,6 @@ namespace MenuOption { const QString ShowOtherLookAtVectors = "Show Other Eye Vectors"; const QString EnableLookAtSnapping = "Enable LookAt Snapping"; const QString ShowRealtimeEntityStats = "Show Realtime Entity Stats"; - const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; const QString SimulateEyeTracking = "Simulate"; const QString SMIEyeTracking = "SMI Eye Tracking"; const QString SparseTextureManagement = "Enable Sparse Texture Management"; diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 714cb91b3f..5a7417cb49 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -36,7 +36,6 @@ Q_DECLARE_LOGGING_CATEGORY(displayplugins) -const char* StandingHMDSensorMode { "Standing HMD Sensor Mode" }; // this probably shouldn't be hardcoded here const char* OpenVrThreadedSubmit { "OpenVR Threaded Submit" }; // this probably shouldn't be hardcoded here PoseData _nextRenderPoseData; @@ -451,7 +450,6 @@ bool OpenVrDisplayPlugin::internalActivate() { qDebug() << "OpenVR Threaded submit enabled: " << _threadedSubmit; _openVrDisplayActive = true; - _container->setIsOptionChecked(StandingHMDSensorMode, true); _system->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y); // Recommended render target size is per-eye, so double the X size for // left + right eyes @@ -507,7 +505,6 @@ void OpenVrDisplayPlugin::internalDeactivate() { Parent::internalDeactivate(); _openVrDisplayActive = false; - _container->setIsOptionChecked(StandingHMDSensorMode, false); if (_system) { // TODO: Invalidate poses. It's fine if someone else sets these shared values, but we're about to stop updating them, and // we don't want ViveControllerManager to consider old values to be valid. From d4d2f3c9573f375a8af51886a8e468a0c9500386 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 14 May 2018 16:32:04 -0700 Subject: [PATCH 148/152] Moved ownership of test location into the Test Scripting class. --- interface/src/Application.cpp | 10 +++++----- interface/src/Application.h | 3 --- interface/src/scripting/TestScriptingInterface.cpp | 9 ++++----- interface/src/scripting/TestScriptingInterface.h | 8 ++++++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 08550a81f0..61ed5acdd2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1033,7 +1033,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QFileInfo fileInfo(path); if (fileInfo.isDir() && fileInfo.isWritable()) { - testResultsLocation = path; + TestScriptingInterface::getInstance()->setTestResultsLocation(path); } } } @@ -7591,8 +7591,8 @@ void Application::loadAvatarBrowser() const { void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) { postLambdaEvent([notify, includeAnimated, aspectRatio, filename, this] { // Get a screenshot and save it - QString path = - Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, testResultsLocation); + QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename, + TestScriptingInterface::getInstance()->getTestResultsLocation()); // If we're not doing an animated snapshot as well... if (!includeAnimated) { @@ -7607,8 +7607,8 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa void Application::takeSecondaryCameraSnapshot(const QString& filename) { postLambdaEvent([filename, this] { - QString snapshotPath = - Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename, testResultsLocation); + QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename, + TestScriptingInterface::getInstance()->getTestResultsLocation()); emit DependencyManager::get()->stillSnapshotTaken(snapshotPath, true); }); diff --git a/interface/src/Application.h b/interface/src/Application.h index d61e986e55..17e28f0e6e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -419,8 +419,6 @@ public slots: void updateVerboseLogging(); Q_INVOKABLE void openAndroidActivity(const QString& activityName); - QString getTestResultsLocation() { return testResultsLocation; }; - private slots: void onDesktopRootItemCreated(QQuickItem* qmlContext); void onDesktopRootContextCreated(QQmlContext* qmlContext); @@ -754,7 +752,6 @@ private: std::atomic _pendingIdleEvent { true }; std::atomic _pendingRenderEvent { true }; - QString testResultsLocation; bool quitWhenFinished { false }; }; #endif // hifi_Application_h diff --git a/interface/src/scripting/TestScriptingInterface.cpp b/interface/src/scripting/TestScriptingInterface.cpp index 15a024fa03..700994c517 100644 --- a/interface/src/scripting/TestScriptingInterface.cpp +++ b/interface/src/scripting/TestScriptingInterface.cpp @@ -162,8 +162,7 @@ void TestScriptingInterface::clearCaches() { // Writes a JSON object from javascript to a file void TestScriptingInterface::saveObject(QVariant variant, const QString& filename) { - QString testResultsLocation = qApp->getTestResultsLocation(); - if (testResultsLocation.isNull()) { + if (_testResultsLocation.isNull()) { return; } @@ -176,11 +175,11 @@ void TestScriptingInterface::saveObject(QVariant variant, const QString& filenam QByteArray jsonData = jsonDocument.toJson(); // Append trailing slash if needed - if (testResultsLocation.right(1) != "/") { - testResultsLocation += "/"; + if (_testResultsLocation.right(1) != "/") { + _testResultsLocation += "/"; } - QString filepath = QDir::cleanPath(testResultsLocation + filename); + QString filepath = QDir::cleanPath(_testResultsLocation + filename); QFile file(filepath); file.open(QFile::WriteOnly); diff --git a/interface/src/scripting/TestScriptingInterface.h b/interface/src/scripting/TestScriptingInterface.h index 4b469244d1..5666417727 100644 --- a/interface/src/scripting/TestScriptingInterface.h +++ b/interface/src/scripting/TestScriptingInterface.h @@ -18,6 +18,10 @@ class QScriptValue; class TestScriptingInterface : public QObject { Q_OBJECT +public: + void setTestResultsLocation(const QString path) { _testResultsLocation = path; } + const QString& getTestResultsLocation() { return _testResultsLocation; }; + public slots: static TestScriptingInterface* getInstance(); @@ -46,7 +50,6 @@ public slots: */ void waitIdle(); - bool waitForConnection(qint64 maxWaitMs = 10000); void wait(int milliseconds); @@ -90,6 +93,7 @@ public slots: private: bool waitForCondition(qint64 maxWaitMs, std::function condition); + QString _testResultsLocation; }; -#endif // hifi_TestScriptingInterface_h +#endif // hifi_TestScriptingInterface_h From 78a8e8e500af6e00dd3ab9311ba06257b83856b0 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 5 May 2018 11:16:03 -0700 Subject: [PATCH 149/152] quiet asan warning --- interface/src/ui/overlays/Overlays.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index cf1151b46a..3ff782da99 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -60,7 +60,7 @@ public: bool intersects { false }; OverlayID overlayID { UNKNOWN_OVERLAY_ID }; float distance { 0 }; - BoxFace face; + BoxFace face { UNKNOWN_FACE }; glm::vec3 surfaceNormal; glm::vec3 intersection; QVariantMap extraInfo; From 79b5882c73143a8eea2af42e72609402c75ebd2f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 5 May 2018 11:16:28 -0700 Subject: [PATCH 150/152] quiet compiler when building with clang on Linux --- tests-manual/render-texture-load/src/GLIHelpers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests-manual/render-texture-load/src/GLIHelpers.h b/tests-manual/render-texture-load/src/GLIHelpers.h index 886176e874..a5d4f71bb3 100644 --- a/tests-manual/render-texture-load/src/GLIHelpers.h +++ b/tests-manual/render-texture-load/src/GLIHelpers.h @@ -15,7 +15,7 @@ // Work around for a bug in the MSVC compiler that chokes when you use GLI and Qt headers together. #define gli glm -#ifdef Q_OS_MAC +#if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wignored-qualifiers" @@ -33,7 +33,7 @@ #include -#ifdef Q_OS_MAC +#if defined(__clang__) #pragma clang diagnostic pop #endif From 306b8cc68ab7f1080b72578c72f18e89b57df21e Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Tue, 15 May 2018 15:14:17 -0300 Subject: [PATCH 151/152] Set HomeActivity transparent to avoid texture corruption (black and white) --- android/app/src/main/AndroidManifest.xml | 2 +- .../hifiinterface/InterfaceActivity.java | 13 ++---- .../hifiinterface/SplashActivity.java | 7 +-- .../app/src/main/res/layout/activity_home.xml | 3 +- .../app/src/main/res/layout/content_home.xml | 1 + interface/src/Application.cpp | 4 -- .../Basic2DWindowOpenGLDisplayPlugin.cpp | 46 +++++++------------ 7 files changed, 27 insertions(+), 49 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 282905a6a8..1b6f3b1304 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -42,7 +42,7 @@ android:name=".HomeActivity" android:label="@string/home" android:screenOrientation="portrait" - android:theme="@style/AppTheme.NoActionBar"> + android:theme="@style/Theme.AppCompat.Translucent.NoActionBar"> { - startActivity(new Intent(this, HomeActivity.class)); - new Handler(getMainLooper()).postDelayed(() -> SplashActivity.this.finish(), 1000); - }, 500); + startActivity(new Intent(this, HomeActivity.class)); // + 2 sec + SplashActivity.this.finish(); } } diff --git a/android/app/src/main/res/layout/activity_home.xml b/android/app/src/main/res/layout/activity_home.xml index 0269672a29..91fb8603cd 100644 --- a/android/app/src/main/res/layout/activity_home.xml +++ b/android/app/src/main/res/layout/activity_home.xml @@ -18,7 +18,7 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" - android:background="?attr/colorPrimaryDark" + android:background="@color/colorPrimaryDark" android:elevation="4dp" /> @@ -33,6 +33,7 @@ android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" + android:background="@color/colorPrimaryDark" app:menu="@menu/menu_home" > diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2852cb38c8..eda8b9bf12 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -8192,15 +8192,11 @@ void Application::openAndroidActivity(const QString& activityName) { void Application::enterBackground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "stop", Qt::BlockingQueuedConnection); - getActiveDisplayPlugin()->deactivate(); } void Application::enterForeground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "start", Qt::BlockingQueuedConnection); - if (!getActiveDisplayPlugin() || !getActiveDisplayPlugin()->activate()) { - qWarning() << "Could not re-activate display plugin"; - } } #endif diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 7c27fab591..09b9b7f8f9 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -131,44 +131,32 @@ void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() { // render stick base auto stickBaseTransform = DependencyManager::get()->getPoint2DTransform(virtualPadManager.getLeftVirtualPad()->getFirstTouch(), _virtualPadPixelSize, _virtualPadPixelSize); - render([&](gpu::Batch& batch) { - batch.enableStereo(false); - batch.setProjectionTransform(mat4()); - batch.setPipeline(_cursorPipeline); - batch.setResourceTexture(0, _virtualPadStickBaseTexture); - batch.resetViewTransform(); - batch.setModelTransform(stickBaseTransform); - batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize())); - batch.draw(gpu::TRIANGLE_STRIP, 4); - }); - // render stick head auto stickTransform = DependencyManager::get()->getPoint2DTransform(virtualPadManager.getLeftVirtualPad()->getCurrentTouch(), - _virtualPadPixelSize, _virtualPadPixelSize); + _virtualPadPixelSize, _virtualPadPixelSize); + auto jumpTransform = DependencyManager::get()->getPoint2DTransform(virtualPadManager.getJumpButtonPosition(), + _virtualPadJumpBtnPixelSize, _virtualPadJumpBtnPixelSize); + render([&](gpu::Batch& batch) { batch.enableStereo(false); + batch.setFramebuffer(_compositeFramebuffer); + batch.resetViewTransform(); batch.setProjectionTransform(mat4()); batch.setPipeline(_cursorPipeline); - batch.setResourceTexture(0, _virtualPadStickTexture); - batch.resetViewTransform(); - batch.setModelTransform(stickTransform); - batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize())); + + batch.setResourceTexture(0, _virtualPadStickBaseTexture); + batch.setModelTransform(stickBaseTransform); batch.draw(gpu::TRIANGLE_STRIP, 4); - }); - if (!virtualPadManager.getLeftVirtualPad()->isBeingTouched()) { - // render stick head - auto jumpTransform = DependencyManager::get()->getPoint2DTransform(virtualPadManager.getJumpButtonPosition(), - _virtualPadJumpBtnPixelSize, _virtualPadJumpBtnPixelSize); - render([&](gpu::Batch& batch) { - batch.enableStereo(false); - batch.setProjectionTransform(mat4()); - batch.setPipeline(_cursorPipeline); + + batch.setResourceTexture(0, _virtualPadStickTexture); + batch.setModelTransform(stickTransform); + batch.draw(gpu::TRIANGLE_STRIP, 4); + + if (!virtualPadManager.getLeftVirtualPad()->isBeingTouched()) { batch.setResourceTexture(0, _virtualPadJumpBtnTexture); - batch.resetViewTransform(); batch.setModelTransform(jumpTransform); - batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize())); batch.draw(gpu::TRIANGLE_STRIP, 4); - }); - } + } + }); } #endif Parent::compositeExtra(); From b80597a4361cab1508c7a6eb09df501cf0bc38f7 Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Tue, 15 May 2018 15:51:11 -0300 Subject: [PATCH 152/152] Restore display plugin activation/deactivation --- interface/src/Application.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eda8b9bf12..c03b708af7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -8192,11 +8192,17 @@ void Application::openAndroidActivity(const QString& activityName) { void Application::enterBackground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "stop", Qt::BlockingQueuedConnection); + if (getActiveDisplayPlugin()->isActive()) { + getActiveDisplayPlugin()->deactivate(); + } } void Application::enterForeground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "start", Qt::BlockingQueuedConnection); + if (!getActiveDisplayPlugin() || getActiveDisplayPlugin()->isActive() || !getActiveDisplayPlugin()->activate()) { + qWarning() << "Could not re-activate display plugin"; + } } #endif