From ded1a1eb020ec7fcdcac1fbdbf32e055ff49c924 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 17 Jun 2017 14:32:59 -0700 Subject: [PATCH 1/3] Prevent cache ejection of textures in use --- libraries/gpu-gl/src/gpu/gl/GLTexture.cpp | 15 ++- libraries/gpu/src/gpu/Texture.h | 8 +- libraries/gpu/src/gpu/Texture_ktx.cpp | 95 +++++++++++++------ .../src/model-networking/KTXCache.h | 2 +- .../src/model-networking/TextureCache.cpp | 11 ++- .../src => shared/src/shared}/FileCache.cpp | 13 ++- .../src => shared/src/shared}/FileCache.h | 2 +- .../src/FileCacheTests.cpp | 0 .../src/FileCacheTests.h | 0 9 files changed, 102 insertions(+), 44 deletions(-) rename libraries/{networking/src => shared/src/shared}/FileCache.cpp (97%) rename libraries/{networking/src => shared/src/shared}/FileCache.h (98%) rename tests/{networking => shared}/src/FileCacheTests.cpp (100%) rename tests/{networking => shared}/src/FileCacheTests.h (100%) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp index 88e5cde330..4161242a24 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.cpp @@ -223,12 +223,21 @@ TransferJob::TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t t // Buffering can invoke disk IO, so it should be off of the main and render threads _bufferingLambda = [=] { - _mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face)->createView(_transferSize, _transferOffset); + auto mipStorage = _parent._gpuObject.accessStoredMipFace(sourceMip, face); + if (mipStorage) { + _mipData = mipStorage->createView(_transferSize, _transferOffset); + } else { + qCWarning(gpugllogging) << "Buffering failed because mip could not be retrieved from texture " << _parent._source.c_str() ; + } }; _transferLambda = [=] { - _parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format, type, _mipData->size(), _mipData->readData()); - _mipData.reset(); + if (_mipData) { + _parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format, type, _mipData->size(), _mipData->readData()); + _mipData.reset(); + } else { + qCWarning(gpugllogging) << "Transfer failed because mip could not be retrieved from texture " << _parent._source.c_str(); + } }; } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 211dc7b8ce..1877b494cf 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -18,7 +18,7 @@ #include #include - +#include #include "Forward.h" #include "Resource.h" #include "Metric.h" @@ -311,6 +311,7 @@ public: class KtxStorage : public Storage { public: KtxStorage(const std::string& filename); + KtxStorage(const cache::FilePointer& file); PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override; Size getMipFaceSize(uint16 level, uint8 face = 0) const override; bool isMipAvailable(uint16 level, uint8 face = 0) const override; @@ -328,6 +329,7 @@ public: mutable std::weak_ptr _cacheFile; std::string _filename; + cache::FilePointer _cacheEntry; std::atomic _minMipLevelAvailable; size_t _offsetToMinMipKV; @@ -499,6 +501,7 @@ public: void setStorage(std::unique_ptr& newStorage); void setKtxBacking(const std::string& filename); + void setKtxBacking(const cache::FilePointer& cacheEntry); // Usage is a a set of flags providing Semantic about the usage of the Texture. void setUsage(const Usage& usage) { _usage = usage; } @@ -529,8 +532,9 @@ public: // Serialize a texture into a KTX file static ktx::KTXUniquePointer serialize(const Texture& texture); + static TexturePointer build(const ktx::KTXDescriptor& descriptor); static TexturePointer unserialize(const std::string& ktxFile); - static TexturePointer unserialize(const std::string& ktxFile, const ktx::KTXDescriptor& descriptor); + static TexturePointer unserialize(const cache::FilePointer& cacheEntry); static bool evalKTXFormat(const Element& mipFormat, const Element& texelFormat, ktx::Header& header); static bool evalTextureFormat(const ktx::Header& header, Element& mipFormat, Element& texelFormat); diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index f455fde009..14fd983ec2 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -154,6 +154,10 @@ struct IrradianceKTXPayload { }; const std::string IrradianceKTXPayload::KEY{ "hifi.irradianceSH" }; +KtxStorage::KtxStorage(const cache::FilePointer& cacheEntry) : KtxStorage(cacheEntry->getFilepath()) { + _cacheEntry = cacheEntry; +} + KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) { { // We are doing a lot of work here just to get descriptor data @@ -295,20 +299,35 @@ void KtxStorage::assignMipFaceData(uint16 level, uint8 face, const storage::Stor throw std::runtime_error("Invalid call"); } +bool validKtx(const std::string& filename) { + ktx::StoragePointer storage { new storage::FileStorage(filename.c_str()) }; + auto ktxPointer = ktx::KTX::create(storage); + if (!ktxPointer) { + return false; + } + return true; +} + void Texture::setKtxBacking(const std::string& filename) { // Check the KTX file for validity before using it as backing storage - { - ktx::StoragePointer storage { new storage::FileStorage(filename.c_str()) }; - auto ktxPointer = ktx::KTX::create(storage); - if (!ktxPointer) { - return; - } + if (!validKtx(filename)) { + return; } auto newBacking = std::unique_ptr(new KtxStorage(filename)); setStorage(newBacking); } +void Texture::setKtxBacking(const cache::FilePointer& cacheEntry) { + // Check the KTX file for validity before using it as backing storage + if (!validKtx(cacheEntry->getFilepath())) { + return; + } + + auto newBacking = std::unique_ptr(new KtxStorage(cacheEntry)); + setStorage(newBacking); +} + ktx::KTXUniquePointer Texture::serialize(const Texture& texture) { ktx::Header header; @@ -442,21 +461,10 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) { return ktxBuffer; } -TexturePointer Texture::unserialize(const std::string& ktxfile) { - std::unique_ptr ktxPointer = ktx::KTX::create(std::make_shared(ktxfile.c_str())); - if (!ktxPointer) { - return nullptr; - } - - ktx::KTXDescriptor descriptor { ktxPointer->toDescriptor() }; - return unserialize(ktxfile, ktxPointer->toDescriptor()); -} - -TexturePointer Texture::unserialize(const std::string& ktxfile, const ktx::KTXDescriptor& descriptor) { - const auto& header = descriptor.header; - +TexturePointer Texture::build(const ktx::KTXDescriptor& descriptor) { Format mipFormat = Format::COLOR_BGRA_32; Format texelFormat = Format::COLOR_SRGBA_32; + const auto& header = descriptor.header; if (!Texture::evalTextureFormat(header, mipFormat, texelFormat)) { return nullptr; @@ -485,20 +493,19 @@ TexturePointer Texture::unserialize(const std::string& ktxfile, const ktx::KTXDe } auto texture = create(gpuktxKeyValue._usageType, - type, - texelFormat, - header.getPixelWidth(), - header.getPixelHeight(), - header.getPixelDepth(), - 1, // num Samples - header.getNumberOfSlices(), - header.getNumberOfLevels(), - gpuktxKeyValue._samplerDesc); + type, + texelFormat, + header.getPixelWidth(), + header.getPixelHeight(), + header.getPixelDepth(), + 1, // num Samples + header.getNumberOfSlices(), + header.getNumberOfLevels(), + gpuktxKeyValue._samplerDesc); texture->setUsage(gpuktxKeyValue._usage); // Assing the mips availables texture->setStoredMipFormat(mipFormat); - texture->setKtxBacking(ktxfile); IrradianceKTXPayload irradianceKtxKeyValue; if (IrradianceKTXPayload::findInKeyValues(descriptor.keyValues, irradianceKtxKeyValue)) { @@ -508,6 +515,36 @@ TexturePointer Texture::unserialize(const std::string& ktxfile, const ktx::KTXDe return texture; } + + +TexturePointer Texture::unserialize(const cache::FilePointer& cacheEntry) { + std::unique_ptr ktxPointer = ktx::KTX::create(std::make_shared(cacheEntry->getFilepath().c_str())); + if (!ktxPointer) { + return nullptr; + } + + auto texture = build(ktxPointer->toDescriptor()); + if (texture) { + texture->setKtxBacking(cacheEntry); + } + + return texture; +} + +TexturePointer Texture::unserialize(const std::string& ktxfile) { + std::unique_ptr ktxPointer = ktx::KTX::create(std::make_shared(ktxfile.c_str())); + if (!ktxPointer) { + return nullptr; + } + + auto texture = build(ktxPointer->toDescriptor()); + if (texture) { + texture->setKtxBacking(ktxfile); + } + + return texture; +} + bool Texture::evalKTXFormat(const Element& mipFormat, const Element& texelFormat, ktx::Header& header) { if (texelFormat == Format::COLOR_RGBA_32 && mipFormat == Format::COLOR_BGRA_32) { header.setUncompressed(ktx::GLType::UNSIGNED_BYTE, 1, ktx::GLFormat::BGRA, ktx::GLInternalFormat::RGBA8, ktx::GLBaseInternalFormat::RGBA); diff --git a/libraries/model-networking/src/model-networking/KTXCache.h b/libraries/model-networking/src/model-networking/KTXCache.h index 5617019c52..a919c88bd7 100644 --- a/libraries/model-networking/src/model-networking/KTXCache.h +++ b/libraries/model-networking/src/model-networking/KTXCache.h @@ -14,7 +14,7 @@ #include -#include +#include namespace ktx { class KTX; diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 8683d56b6b..15eb4be839 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -612,9 +612,10 @@ void NetworkTexture::maybeHandleFinishedInitialLoad() { if (!texture) { KTXFilePointer ktxFile = textureCache->_ktxCache.getFile(hash); if (ktxFile) { - texture = gpu::Texture::unserialize(ktxFile->getFilepath()); + texture = gpu::Texture::unserialize(ktxFile); if (texture) { texture = textureCache->cacheTextureByHash(hash, texture); + _file = ktxFile; } } } @@ -644,8 +645,8 @@ void NetworkTexture::maybeHandleFinishedInitialLoad() { auto newKtxDescriptor = memKtx->toDescriptor(); - texture = gpu::Texture::unserialize(_file->getFilepath(), newKtxDescriptor); - texture->setKtxBacking(file->getFilepath()); + texture = gpu::Texture::build(newKtxDescriptor); + texture->setKtxBacking(file); texture->setSource(filename); auto& images = _originalKtxDescriptor->images; @@ -796,7 +797,7 @@ void ImageReader::read() { if (!texture) { KTXFilePointer ktxFile = textureCache->_ktxCache.getFile(hash); if (ktxFile) { - texture = gpu::Texture::unserialize(ktxFile->getFilepath()); + texture = gpu::Texture::unserialize(ktxFile); if (texture) { texture = textureCache->cacheTextureByHash(hash, texture); } else { @@ -848,7 +849,7 @@ void ImageReader::read() { if (!networkTexture->_file) { qCWarning(modelnetworking) << _url << "file cache failed"; } else { - texture->setKtxBacking(networkTexture->_file->getFilepath()); + texture->setKtxBacking(networkTexture->_file); } } else { qCWarning(modelnetworking) << "Unable to serialize texture to KTX " << _url; diff --git a/libraries/networking/src/FileCache.cpp b/libraries/shared/src/shared/FileCache.cpp similarity index 97% rename from libraries/networking/src/FileCache.cpp rename to libraries/shared/src/shared/FileCache.cpp index 43bab67ec7..801c68e302 100644 --- a/libraries/networking/src/FileCache.cpp +++ b/libraries/shared/src/shared/FileCache.cpp @@ -21,8 +21,8 @@ #include #include -#include -#include +#include "../PathUtils.h" +#include "../NumericalConstants.h" #ifdef Q_OS_WIN #include @@ -132,9 +132,16 @@ FilePointer FileCache::addFile(Metadata&& metadata, const std::string& filepath) } FilePointer FileCache::writeFile(const char* data, File::Metadata&& metadata, bool overwrite) { + FilePointer file; + + if (0 == metadata.length) { + qCWarning(file_cache) << "Cannot store empty files in the cache"; + return file; + } + + Lock lock(_mutex); - FilePointer file; if (!_initialized) { qCWarning(file_cache) << "File cache used before initialization"; return file; diff --git a/libraries/networking/src/FileCache.h b/libraries/shared/src/shared/FileCache.h similarity index 98% rename from libraries/networking/src/FileCache.h rename to libraries/shared/src/shared/FileCache.h index 089d99273a..25210af1da 100644 --- a/libraries/networking/src/FileCache.h +++ b/libraries/shared/src/shared/FileCache.h @@ -143,7 +143,7 @@ public: const Key& getKey() const { return _key; } const size_t& getLength() const { return _length; } - std::string getFilepath() const { return _filepath; } + const std::string& getFilepath() const { return _filepath; } virtual ~File(); /// overrides should call File::deleter to maintain caching behavior diff --git a/tests/networking/src/FileCacheTests.cpp b/tests/shared/src/FileCacheTests.cpp similarity index 100% rename from tests/networking/src/FileCacheTests.cpp rename to tests/shared/src/FileCacheTests.cpp diff --git a/tests/networking/src/FileCacheTests.h b/tests/shared/src/FileCacheTests.h similarity index 100% rename from tests/networking/src/FileCacheTests.h rename to tests/shared/src/FileCacheTests.h From 03f3a7eefd9a52063a1186312f6c9115702bbacc Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 19 Jun 2017 17:34:50 -0700 Subject: [PATCH 2/3] Fix the local lights issue, and correct the script relying on the Render.getConfig(), this one is on me... --- libraries/render-utils/src/LightClusters.cpp | 8 +--- .../utilities/render/ambientOcclusionPass.qml | 13 ++--- .../developer/utilities/render/culling.qml | 15 +++--- .../render/debugAmbientOcclusionPass.js | 2 +- .../render/debugSubsurfaceScattering.js | 2 +- .../utilities/render/deferredLighting.qml | 47 ++++++++++--------- .../utilities/render/lightClustering.qml | 47 ++++++++++--------- scripts/developer/utilities/render/stats.qml | 21 +++++---- .../developer/utilities/render/statsGPU.qml | 23 ++++----- .../utilities/render/subsurfaceScattering.qml | 35 +++++++------- .../utilities/render/surfaceGeometryPass.qml | 11 +++-- .../utilities/render/textureMonitor.qml | 3 +- 12 files changed, 116 insertions(+), 111 deletions(-) diff --git a/libraries/render-utils/src/LightClusters.cpp b/libraries/render-utils/src/LightClusters.cpp index 7e04b1c2a4..e35120eb5b 100644 --- a/libraries/render-utils/src/LightClusters.cpp +++ b/libraries/render-utils/src/LightClusters.cpp @@ -548,6 +548,7 @@ glm::ivec3 LightClusters::updateClusters() { LightClusteringPass::LightClusteringPass() { + _lightClusters = std::make_shared(); } @@ -566,12 +567,7 @@ void LightClusteringPass::run(const render::RenderContextPointer& renderContext, auto deferredTransform = inputs.get0(); auto lightingModel = inputs.get1(); auto surfaceGeometryFramebuffer = inputs.get2(); - - - if (!_lightClusters) { - _lightClusters = std::make_shared(); - } - + // first update the Grid with the new frustum if (!_freeze) { _lightClusters->updateFrustum(args->getViewFrustum()); diff --git a/scripts/developer/utilities/render/ambientOcclusionPass.qml b/scripts/developer/utilities/render/ambientOcclusionPass.qml index 3ebc80d2f1..86f55ef6aa 100644 --- a/scripts/developer/utilities/render/ambientOcclusionPass.qml +++ b/scripts/developer/utilities/render/ambientOcclusionPass.qml @@ -13,6 +13,7 @@ import "configSlider" import "../lib/plotperf" Column { + property var mainViewTask: Render.getConfig("RenderMainView") spacing: 8 Column { id: surfaceGeometry @@ -32,7 +33,7 @@ Column { ConfigSlider { label: qsTr(modelData.split(":")[0]) integral: (modelData.split(":")[3] == 'true') - config: Render.getConfig("AmbientOcclusion") + config: mainViewTask.getConfig("AmbientOcclusion") property: modelData.split(":")[1] max: modelData.split(":")[2] min: 0.0 @@ -50,8 +51,8 @@ Column { ] CheckBox { text: qsTr(modelData.split(":")[0]) - checked: Render.getConfig("AmbientOcclusion")[modelData.split(":")[1]] - onCheckedChanged: { Render.getConfig("AmbientOcclusion")[modelData.split(":")[1]] = checked } + checked: mainViewTask.getConfig("AmbientOcclusion")[modelData.split(":")[1]] + onCheckedChanged: { mainViewTask.getConfig("AmbientOcclusion")[modelData.split(":")[1]] = checked } } } } @@ -62,8 +63,8 @@ Column { ] CheckBox { text: qsTr(modelData.split(":")[0]) - checked: Render.getConfig("DebugAmbientOcclusion")[modelData.split(":")[1]] - onCheckedChanged: { Render.getConfig("DebugAmbientOcclusion")[modelData.split(":")[1]] = checked } + checked: mainViewTask.getConfig("DebugAmbientOcclusion")[modelData.split(":")[1]] + onCheckedChanged: { mainViewTask.getConfig("DebugAmbientOcclusion")[modelData.split(":")[1]] = checked } } } } @@ -72,7 +73,7 @@ Column { PlotPerf { title: "Timing" height: 50 - object: Render.getConfig("AmbientOcclusion") + object: mainViewTask.getConfig("AmbientOcclusion") valueUnit: "ms" valueScale: 1 valueNumDigits: "3" diff --git a/scripts/developer/utilities/render/culling.qml b/scripts/developer/utilities/render/culling.qml index e3f5e67bbe..3c3c0f67d9 100644 --- a/scripts/developer/utilities/render/culling.qml +++ b/scripts/developer/utilities/render/culling.qml @@ -14,8 +14,9 @@ import "configSlider" Column { id: root spacing: 8 - property var sceneOctree: Render.getConfig("DrawSceneOctree"); - property var itemSelection: Render.getConfig("DrawItemSelection"); + property var mainViewTask: Render.getConfig("RenderMainView"); + property var sceneOctree: mainViewTask.getConfig("DrawSceneOctree"); + property var itemSelection: mainViewTask.getConfig("DrawItemSelection"); Component.onCompleted: { sceneOctree.enabled = true; @@ -30,8 +31,8 @@ Column { Component.onDestruction: { sceneOctree.enabled = false; itemSelection.enabled = false; - Render.getConfig("FetchSceneSelection").freezeFrustum = false; - Render.getConfig("CullSceneSelection").freezeFrustum = false; + mainViewTask.getConfig("FetchSceneSelection").freezeFrustum = false; + mainViewTask.getConfig("CullSceneSelection").freezeFrustum = false; } GroupBox { @@ -45,8 +46,8 @@ Column { text: "Freeze Culling Frustum" checked: false onCheckedChanged: { - Render.getConfig("FetchSceneSelection").freezeFrustum = checked; - Render.getConfig("CullSceneSelection").freezeFrustum = checked; + mainViewTask.getConfig("FetchSceneSelection").freezeFrustum = checked; + mainViewTask.getConfig("CullSceneSelection").freezeFrustum = checked; } } Label { @@ -103,7 +104,7 @@ Column { ConfigSlider { label: qsTr(modelData.split(":")[0]) integral: true - config: Render.getConfig(modelData.split(":")[1]) + config: mainViewTask.getConfig(modelData.split(":")[1]) property: "maxDrawn" max: config.numDrawn min: -1 diff --git a/scripts/developer/utilities/render/debugAmbientOcclusionPass.js b/scripts/developer/utilities/render/debugAmbientOcclusionPass.js index c57fdf0526..e93d153486 100644 --- a/scripts/developer/utilities/render/debugAmbientOcclusionPass.js +++ b/scripts/developer/utilities/render/debugAmbientOcclusionPass.js @@ -34,5 +34,5 @@ function setDebugCursor(x, y) { nx = (x / Window.innerWidth); ny = 1.0 - ((y) / (Window.innerHeight - 32)); - Render.getConfig("DebugAmbientOcclusion").debugCursorTexcoord = { x: nx, y: ny }; + Render.getConfig("RenderMainView").getConfig("DebugAmbientOcclusion").debugCursorTexcoord = { x: nx, y: ny }; } diff --git a/scripts/developer/utilities/render/debugSubsurfaceScattering.js b/scripts/developer/utilities/render/debugSubsurfaceScattering.js index 72b15546e0..c578ef0f06 100644 --- a/scripts/developer/utilities/render/debugSubsurfaceScattering.js +++ b/scripts/developer/utilities/render/debugSubsurfaceScattering.js @@ -33,5 +33,5 @@ function setDebugCursor(x, y) { nx = (x / Window.innerWidth); ny = 1.0 - ((y) / (Window.innerHeight - 32)); - Render.getConfig("DebugScattering").debugCursorTexcoord = { x: nx, y: ny }; + Render.getConfig("RenderMainView").getConfig("DebugScattering").debugCursorTexcoord = { x: nx, y: ny }; } diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index ff4621a87a..2254b6d95f 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -13,6 +13,7 @@ import "configSlider" Column { spacing: 8 + property var mainViewTask: Render.getConfig("RenderMainView") Row { spacing: 8 @@ -29,8 +30,8 @@ Column { ] CheckBox { text: modelData.split(":")[0] - checked: Render.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] - onCheckedChanged: { Render.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } + checked: mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] + onCheckedChanged: { mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } } } } @@ -49,8 +50,8 @@ Column { ] CheckBox { text: modelData.split(":")[0] - checked: Render.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] - onCheckedChanged: { Render.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } + checked: mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] + onCheckedChanged: { mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } } } } @@ -69,8 +70,8 @@ Column { ] CheckBox { text: modelData.split(":")[0] - checked: Render.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] - onCheckedChanged: { Render.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } + checked: mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] + onCheckedChanged: { mainViewTask.getConfig(modelData.split(":")[1])[modelData.split(":")[2]] = checked } } } } @@ -83,7 +84,7 @@ Column { ConfigSlider { label: qsTr(modelData.split(":")[0]) integral: false - config: Render.getConfig(modelData.split(":")[1]) + config: mainViewTask.getConfig(modelData.split(":")[1]) property: modelData.split(":")[2] max: modelData.split(":")[3] min: modelData.split(":")[4] @@ -107,7 +108,7 @@ Column { ListElement { text: "Filmic"; color: "White" } } width: 200 - onCurrentIndexChanged: { Render.getConfig("ToneMapping")["curve"] = currentIndex } + onCurrentIndexChanged: { mainViewTask.getConfig("ToneMapping")["curve"] = currentIndex } } } } @@ -120,7 +121,7 @@ Column { anchors.left: root.left } - property var config: Render.getConfig("DebugDeferredBuffer") + property var config: mainViewTask.getConfig("DebugDeferredBuffer") function setDebugMode(mode) { framebuffer.config.enabled = (mode != 0); @@ -168,40 +169,40 @@ Column { CheckBox { text: "Opaques" - checked: Render.getConfig("DrawOpaqueBounds")["enabled"] - onCheckedChanged: { Render.getConfig("DrawOpaqueBounds")["enabled"] = checked } + checked: mainViewTask.getConfig("DrawOpaqueBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawOpaqueBounds")["enabled"] = checked } } CheckBox { text: "Transparents" - checked: Render.getConfig("DrawTransparentBounds")["enabled"] - onCheckedChanged: { Render.getConfig("DrawTransparentBounds")["enabled"] = checked } + checked: mainViewTask.getConfig("DrawTransparentBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawTransparentBounds")["enabled"] = checked } } CheckBox { text: "Overlay Opaques" - checked: Render.getConfig("DrawOverlayOpaqueBounds")["enabled"] - onCheckedChanged: { Render.getConfig("DrawOverlayOpaqueBounds")["enabled"] = checked } + checked: mainViewTask.getConfig("DrawOverlayOpaqueBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawOverlayOpaqueBounds")["enabled"] = checked } } CheckBox { text: "Overlay Transparents" - checked: Render.getConfig("DrawOverlayTransparentBounds")["enabled"] - onCheckedChanged: { Render.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked } + checked: mainViewTask.getConfig("DrawOverlayTransparentBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked } } } Column { CheckBox { text: "Metas" - checked: Render.getConfig("DrawMetaBounds")["enabled"] - onCheckedChanged: { Render.getConfig("DrawMetaBounds")["enabled"] = checked } + checked: mainViewTask.getConfig("DrawMetaBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawMetaBounds")["enabled"] = checked } } CheckBox { text: "Lights" - checked: Render.getConfig("DrawLightBounds")["enabled"] - onCheckedChanged: { Render.getConfig("DrawLightBounds")["enabled"] = checked; } + checked: mainViewTask.getConfig("DrawLightBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawLightBounds")["enabled"] = checked; } } CheckBox { text: "Zones" - checked: Render.getConfig("DrawZones")["enabled"] - onCheckedChanged: { Render.getConfig("ZoneRenderer")["enabled"] = checked; Render.getConfig("DrawZones")["enabled"] = checked; } + checked: mainViewTask.getConfig("DrawZones")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("ZoneRenderer")["enabled"] = checked; mainViewTask.getConfig("DrawZones")["enabled"] = checked; } } } } diff --git a/scripts/developer/utilities/render/lightClustering.qml b/scripts/developer/utilities/render/lightClustering.qml index 4db7aa8c39..930fd79db3 100644 --- a/scripts/developer/utilities/render/lightClustering.qml +++ b/scripts/developer/utilities/render/lightClustering.qml @@ -17,18 +17,19 @@ Column { Column { id: lightClustering spacing: 10 + property var mainViewTask: Render.getConfig("RenderMainView"); Column{ PlotPerf { title: "Light CLustering Timing" height: 50 - object: Render.getConfig("LightClustering") + object: mainViewTask.getConfig("LightClustering") valueUnit: "ms" valueScale: 1 valueNumDigits: "4" plots: [ { - object: Render.getConfig("LightClustering"), + object: mainViewTask.getConfig("LightClustering"), prop: "cpuRunTime", label: "time", scale: 1, @@ -40,19 +41,19 @@ Column { PlotPerf { title: "Lights" height: 50 - object: Render.getConfig("LightClustering") + object: mainViewTask.getConfig("LightClustering") valueUnit: "" valueScale: 1 valueNumDigits: "0" plots: [ { - object: Render.getConfig("LightClustering"), + object: mainViewTask.getConfig("LightClustering"), prop: "numClusteredLights", label: "visible", color: "#D959FE" }, { - object: Render.getConfig("LightClustering"), + object: mainViewTask.getConfig("LightClustering"), prop: "numInputLights", label: "input", color: "#FED959" @@ -63,25 +64,25 @@ Column { PlotPerf { title: "Scene Lights" height: 80 - object: Render.getConfig("LightClustering") + object: mainViewTask.getConfig("LightClustering") valueUnit: "" valueScale: 1 valueNumDigits: "0" plots: [ { - object: Render.getConfig("LightClustering"), + object: mainViewTask.getConfig("LightClustering"), prop: "numSceneLights", label: "current", color: "#00B4EF" }, { - object: Render.getConfig("LightClustering"), + object: mainViewTask.getConfig("LightClustering"), prop: "numFreeSceneLights", label: "free", color: "#1AC567" }, { - object: Render.getConfig("LightClustering"), + object: mainViewTask.getConfig("LightClustering"), prop: "numAllocatedSceneLights", label: "allocated", color: "#9495FF" @@ -92,7 +93,7 @@ Column { ConfigSlider { label: qsTr("Range Near [m]") integral: false - config: Render.getConfig("LightClustering") + config: mainViewTask.getConfig("LightClustering") property: "rangeNear" max: 20.0 min: 0.1 @@ -100,7 +101,7 @@ Column { ConfigSlider { label: qsTr("Range Far [m]") integral: false - config: Render.getConfig("LightClustering") + config: mainViewTask.getConfig("LightClustering") property: "rangeFar" max: 500.0 min: 100.0 @@ -108,7 +109,7 @@ Column { ConfigSlider { label: qsTr("Grid X") integral: true - config: Render.getConfig("LightClustering") + config: mainViewTask.getConfig("LightClustering") property: "dimX" max: 32 min: 1 @@ -116,7 +117,7 @@ Column { ConfigSlider { label: qsTr("Grid Y") integral: true - config: Render.getConfig("LightClustering") + config: mainViewTask.getConfig("LightClustering") property: "dimY" max: 32 min: 1 @@ -124,33 +125,33 @@ Column { ConfigSlider { label: qsTr("Grid Z") integral: true - config: Render.getConfig("LightClustering") + config: mainViewTask.getConfig("LightClustering") property: "dimZ" max: 31 min: 1 } CheckBox { text: "Freeze" - checked: Render.getConfig("LightClustering")["freeze"] - onCheckedChanged: { Render.getConfig("LightClustering")["freeze"] = checked } + checked: mainViewTask.getConfig("LightClustering")["freeze"] + onCheckedChanged: { mainViewTask.getConfig("LightClustering")["freeze"] = checked } } CheckBox { text: "Draw Grid" - checked: Render.getConfig("DebugLightClusters")["doDrawGrid"] - onCheckedChanged: { Render.getConfig("DebugLightClusters")["doDrawGrid"] = checked } + checked: mainViewTask.getConfig("DebugLightClusters")["doDrawGrid"] + onCheckedChanged: { mainViewTask.getConfig("DebugLightClusters")["doDrawGrid"] = checked } } CheckBox { text: "Draw Cluster From Depth" - checked: Render.getConfig("DebugLightClusters")["doDrawClusterFromDepth"] - onCheckedChanged: { Render.getConfig("DebugLightClusters")["doDrawClusterFromDepth"] = checked } + checked: mainViewTask.getConfig("DebugLightClusters")["doDrawClusterFromDepth"] + onCheckedChanged: { mainViewTask.getConfig("DebugLightClusters")["doDrawClusterFromDepth"] = checked } } CheckBox { text: "Draw Content" - checked: Render.getConfig("DebugLightClusters")["doDrawContent"] - onCheckedChanged: { Render.getConfig("DebugLightClusters")["doDrawContent"] = checked } + checked: mainViewTask.getConfig("DebugLightClusters")["doDrawContent"] + onCheckedChanged: { mainViewTask.getConfig("DebugLightClusters")["doDrawContent"] = checked } } Label { - text: "Num Cluster Items = " + Render.getConfig("LightClustering")["numClusteredLightReferences"].toFixed(0) + text: "Num Cluster Items = " + mainViewTask.getConfig("LightClustering")["numClusteredLightReferences"].toFixed(0) } } diff --git a/scripts/developer/utilities/render/stats.qml b/scripts/developer/utilities/render/stats.qml index 54e0dc4ce8..064045e8f5 100644 --- a/scripts/developer/utilities/render/stats.qml +++ b/scripts/developer/utilities/render/stats.qml @@ -21,7 +21,8 @@ Item { spacing: 8 anchors.fill:parent - property var config: Render.getConfig("Stats") + property var mainViewTask: Render.getConfig("RenderMainView"); + property var config: mainViewTask.getConfig("Stats") function evalEvenHeight() { // Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ? @@ -182,9 +183,9 @@ Item { ] } - property var drawOpaqueConfig: Render.getConfig("DrawOpaqueDeferred") - property var drawTransparentConfig: Render.getConfig("DrawTransparentDeferred") - property var drawLightConfig: Render.getConfig("DrawLight") + property var drawOpaqueConfig: mainViewTask.getConfig("DrawOpaqueDeferred") + property var drawTransparentConfig: mainViewTask.getConfig("DrawTransparentDeferred") + property var drawLightConfig: mainViewTask.getConfig("DrawLight") PlotPerf { title: "Items" @@ -199,13 +200,13 @@ Item { color: "#1AC567" }, { - object: Render.getConfig("DrawTransparentDeferred"), + object: mainViewTask.getConfig("DrawTransparentDeferred"), prop: "numDrawn", label: "Translucents", color: "#00B4EF" }, { - object: Render.getConfig("DrawLight"), + object: mainViewTask.getConfig("DrawLight"), prop: "numDrawn", label: "Lights", color: "#FED959" @@ -222,25 +223,25 @@ Item { valueNumDigits: "2" plots: [ { - object: Render.getConfig("DrawOpaqueDeferred"), + object: mainViewTask.getConfig("DrawOpaqueDeferred"), prop: "cpuRunTime", label: "Opaques", color: "#1AC567" }, { - object: Render.getConfig("DrawTransparentDeferred"), + object: mainViewTask.getConfig("DrawTransparentDeferred"), prop: "cpuRunTime", label: "Translucents", color: "#00B4EF" }, { - object: Render.getConfig("RenderDeferred"), + object: mainViewTask.getConfig("RenderDeferred"), prop: "cpuRunTime", label: "Lighting", color: "#FED959" }, { - object: Render.getConfig("RenderDeferredTask"), + object: mainViewTask.getConfig("RenderDeferredTask"), prop: "cpuRunTime", label: "RenderFrame", color: "#E2334D" diff --git a/scripts/developer/utilities/render/statsGPU.qml b/scripts/developer/utilities/render/statsGPU.qml index 3d23c2c6dc..b3f5ec6e45 100644 --- a/scripts/developer/utilities/render/statsGPU.qml +++ b/scripts/developer/utilities/render/statsGPU.qml @@ -21,7 +21,8 @@ Item { spacing: 8 anchors.fill:parent - property var config: Render.getConfig("Stats") + property var mainViewTask: Render.getConfig("RenderMainView"); + property var config: mainViewTask.getConfig("Stats") function evalEvenHeight() { // Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ? @@ -38,31 +39,31 @@ Item { valueNumDigits: "4" plots: [ { - object: Render.getConfig("OpaqueRangeTimer"), + object: mainViewTask.getConfig("OpaqueRangeTimer"), prop: "gpuRunTime", label: "Opaque", color: "#FFFFFF" }, { - object: Render.getConfig("LinearDepth"), + object: mainViewTask.getConfig("LinearDepth"), prop: "gpuRunTime", label: "LinearDepth", color: "#00FF00" },{ - object: Render.getConfig("SurfaceGeometry"), + object: mainViewTask.getConfig("SurfaceGeometry"), prop: "gpuRunTime", label: "SurfaceGeometry", color: "#00FFFF" }, { - object: Render.getConfig("RenderDeferred"), + object: mainViewTask.getConfig("RenderDeferred"), prop: "gpuRunTime", label: "DeferredLighting", color: "#FF00FF" } , { - object: Render.getConfig("ToneAndPostRangeTimer"), + object: mainViewTask.getConfig("ToneAndPostRangeTimer"), prop: "gpuRunTime", label: "tone and post", color: "#FF0000" @@ -78,31 +79,31 @@ Item { valueNumDigits: "3" plots: [ { - object: Render.getConfig("OpaqueRangeTimer"), + object: mainViewTask.getConfig("OpaqueRangeTimer"), prop: "batchRunTime", label: "Opaque", color: "#FFFFFF" }, { - object: Render.getConfig("LinearDepth"), + object: mainViewTask.getConfig("LinearDepth"), prop: "batchRunTime", label: "LinearDepth", color: "#00FF00" },{ - object: Render.getConfig("SurfaceGeometry"), + object: mainViewTask.getConfig("SurfaceGeometry"), prop: "batchRunTime", label: "SurfaceGeometry", color: "#00FFFF" }, { - object: Render.getConfig("RenderDeferred"), + object: mainViewTask.getConfig("RenderDeferred"), prop: "batchRunTime", label: "DeferredLighting", color: "#FF00FF" } , { - object: Render.getConfig("ToneAndPostRangeTimer"), + object: mainViewTask.getConfig("ToneAndPostRangeTimer"), prop: "batchRunTime", label: "tone and post", color: "#FF0000" diff --git a/scripts/developer/utilities/render/subsurfaceScattering.qml b/scripts/developer/utilities/render/subsurfaceScattering.qml index 47b960c98b..53bca7f2b8 100644 --- a/scripts/developer/utilities/render/subsurfaceScattering.qml +++ b/scripts/developer/utilities/render/subsurfaceScattering.qml @@ -16,28 +16,29 @@ Column { Column { id: scattering spacing: 10 + property var mainViewTask: Render.getConfig("RenderMainView"); Column{ CheckBox { text: "Scattering" - checked: Render.getConfig("Scattering").enableScattering - onCheckedChanged: { Render.getConfig("Scattering").enableScattering = checked } + checked: mainViewTask.getConfig("Scattering").enableScattering + onCheckedChanged: { mainViewTask.getConfig("Scattering").enableScattering = checked } } CheckBox { text: "Show Scattering BRDF" - checked: Render.getConfig("Scattering").showScatteringBRDF - onCheckedChanged: { Render.getConfig("Scattering").showScatteringBRDF = checked } + checked: mainViewTask.getConfig("Scattering").showScatteringBRDF + onCheckedChanged: { mainViewTask.getConfig("Scattering").showScatteringBRDF = checked } } CheckBox { text: "Show Curvature" - checked: Render.getConfig("Scattering").showCurvature - onCheckedChanged: { Render.getConfig("Scattering").showCurvature = checked } + checked: mainViewTask.getConfig("Scattering").showCurvature + onCheckedChanged: { mainViewTask.getConfig("Scattering").showCurvature = checked } } CheckBox { text: "Show Diffused Normal" - checked: Render.getConfig("Scattering").showDiffusedNormal - onCheckedChanged: { Render.getConfig("Scattering").showDiffusedNormal = checked } + checked: mainViewTask.getConfig("Scattering").showDiffusedNormal + onCheckedChanged: { mainViewTask.getConfig("Scattering").showDiffusedNormal = checked } } Repeater { model: [ "Scattering Bent Red:Scattering:bentRed:2.0", @@ -50,7 +51,7 @@ Column { ConfigSlider { label: qsTr(modelData.split(":")[0]) integral: false - config: Render.getConfig(modelData.split(":")[1]) + config: mainViewTask.getConfig(modelData.split(":")[1]) property: modelData.split(":")[2] max: modelData.split(":")[3] min: 0.0 @@ -58,23 +59,23 @@ Column { } CheckBox { text: "Scattering Profile" - checked: Render.getConfig("DebugScattering").showProfile - onCheckedChanged: { Render.getConfig("DebugScattering").showProfile = checked } + checked: mainViewTask.getConfig("DebugScattering").showProfile + onCheckedChanged: { mainViewTask.getConfig("DebugScattering").showProfile = checked } } CheckBox { text: "Scattering Table" - checked: Render.getConfig("DebugScattering").showLUT - onCheckedChanged: { Render.getConfig("DebugScattering").showLUT = checked } + checked: mainViewTask.getConfig("DebugScattering").showLUT + onCheckedChanged: { mainViewTask.getConfig("DebugScattering").showLUT = checked } } CheckBox { text: "Cursor Pixel" - checked: Render.getConfig("DebugScattering").showCursorPixel - onCheckedChanged: { Render.getConfig("DebugScattering").showCursorPixel = checked } + checked: mainViewTask.getConfig("DebugScattering").showCursorPixel + onCheckedChanged: { mainViewTask.getConfig("DebugScattering").showCursorPixel = checked } } CheckBox { text: "Skin Specular Beckmann" - checked: Render.getConfig("DebugScattering").showSpecularTable - onCheckedChanged: { Render.getConfig("DebugScattering").showSpecularTable = checked } + checked: mainViewTask.getConfig("DebugScattering").showSpecularTable + onCheckedChanged: { mainViewTask.getConfig("DebugScattering").showSpecularTable = checked } } } } diff --git a/scripts/developer/utilities/render/surfaceGeometryPass.qml b/scripts/developer/utilities/render/surfaceGeometryPass.qml index 1ff0efa15d..7e70dceef1 100644 --- a/scripts/developer/utilities/render/surfaceGeometryPass.qml +++ b/scripts/developer/utilities/render/surfaceGeometryPass.qml @@ -16,12 +16,13 @@ Column { Column { id: surfaceGeometry spacing: 10 + property var mainViewTask: Render.getConfig("RenderMainView"); Column{ ConfigSlider { label: qsTr("Depth Threshold [cm]") integral: false - config: Render.getConfig("SurfaceGeometry") + config: mainViewTask.getConfig("SurfaceGeometry") property: "depthThreshold" max: 5.0 min: 0.0 @@ -34,7 +35,7 @@ Column { ConfigSlider { label: qsTr(modelData.split(":")[0]) integral: (modelData.split(":")[3] == 'true') - config: Render.getConfig("SurfaceGeometry") + config: mainViewTask.getConfig("SurfaceGeometry") property: modelData.split(":")[1] max: modelData.split(":")[2] min: 0.0 @@ -42,8 +43,8 @@ Column { } CheckBox { text: "Half Resolution" - checked: Render.getConfig("SurfaceGeometry")["resolutionLevel"] - onCheckedChanged: { Render.getConfig("SurfaceGeometry")["resolutionLevel"] = checked } + checked: mainViewTask.getConfig("SurfaceGeometry")["resolutionLevel"] + onCheckedChanged: { mainViewTask.getConfig("SurfaceGeometry")["resolutionLevel"] = checked } } Repeater { @@ -53,7 +54,7 @@ Column { ConfigSlider { label: qsTr(modelData.split(":")[0]) integral: false - config: Render.getConfig(modelData.split(":")[1]) + config: mainViewTask.getConfig(modelData.split(":")[1]) property: modelData.split(":")[2] max: modelData.split(":")[3] min: 0.0 diff --git a/scripts/developer/utilities/render/textureMonitor.qml b/scripts/developer/utilities/render/textureMonitor.qml index 97cc577ff9..1a6dffab23 100644 --- a/scripts/developer/utilities/render/textureMonitor.qml +++ b/scripts/developer/utilities/render/textureMonitor.qml @@ -22,7 +22,8 @@ Item { spacing: 8 anchors.fill:parent - property var config: Render.getConfig("Stats") + property var mainViewTask: Render.getConfig("RenderMainView"); + property var config: mainViewTask.getConfig("Stats") function evalEvenHeight() { // Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ? From 08b6c4f829998634e8de697767639cbc84b183ad Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 20 Jun 2017 16:44:25 +1200 Subject: [PATCH 3/3] Fix import of JSON with parent-child relationships --- scripts/system/edit.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index a3583e7808..a83d2159bb 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -622,7 +622,7 @@ var toolBar = (function () { })); isActive = active; activeButton.editProperties({isActive: isActive}); - + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); if (!isActive) { @@ -1519,6 +1519,8 @@ function importSVO(importURL) { // entities after they're imported so that they're all the correct distance in front of and with geometric mean // centered on the avatar/camera direction. var deltaPosition = Vec3.ZERO; + var entityPositions = []; + var entityParentIDs = []; var properties = Entities.getEntityProperties(pastedEntityIDs[0], ["type"]); var NO_ADJUST_ENTITY_TYPES = ["Zone", "Light", "ParticleEffect"]; @@ -1534,10 +1536,9 @@ function importSVO(importURL) { var targetPosition = getPositionToCreateEntity(); var deltaParallel = HALF_TREE_SCALE; // Distance to move entities parallel to targetDirection. var deltaPerpendicular = Vec3.ZERO; // Distance to move entities perpendicular to targetDirection. - var entityPositions = []; for (var i = 0, length = pastedEntityIDs.length; i < length; i++) { var properties = Entities.getEntityProperties(pastedEntityIDs[i], ["position", "dimensions", - "registrationPoint", "rotation"]); + "registrationPoint", "rotation", "parentID"]); var adjustedPosition = adjustPositionPerBoundingBox(targetPosition, targetDirection, properties.registrationPoint, properties.dimensions, properties.rotation); var delta = Vec3.subtract(adjustedPosition, properties.position); @@ -1546,6 +1547,7 @@ function importSVO(importURL) { deltaPerpendicular = Vec3.sum(Vec3.subtract(delta, Vec3.multiply(distance, targetDirection)), deltaPerpendicular); entityPositions[i] = properties.position; + entityParentIDs[i] = properties.parentID; } deltaPerpendicular = Vec3.multiply(1 / pastedEntityIDs.length, deltaPerpendicular); deltaPosition = Vec3.sum(Vec3.multiply(deltaParallel, targetDirection), deltaPerpendicular); @@ -1562,9 +1564,11 @@ function importSVO(importURL) { if (!Vec3.equal(deltaPosition, Vec3.ZERO)) { for (var i = 0, length = pastedEntityIDs.length; i < length; i++) { - Entities.editEntity(pastedEntityIDs[i], { - position: Vec3.sum(deltaPosition, entityPositions[i]) - }); + if (Uuid.isNull(entityParentIDs[i])) { + Entities.editEntity(pastedEntityIDs[i], { + position: Vec3.sum(deltaPosition, entityPositions[i]) + }); + } } } }