From 133a8b7d5e85ff6468615e870d3713ca59c45bb9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 11 Sep 2019 18:21:44 -0700 Subject: [PATCH 01/21] a bunch of changes to debug why... --- libraries/gl/src/gl/GLHelpers.cpp | 1 + .../src/graphics-scripting/Forward.h | 3 ++- .../GraphicsScriptingInterface.cpp | 12 +++++++++++ .../graphics-scripting/ScriptableModel.cpp | 7 +++++++ .../utilities/render/materialInspector.js | 2 +- tools/gpu-frame-player/src/RenderThread.cpp | 21 +++++++++++++++++-- tools/gpu-frame-player/src/RenderThread.h | 2 +- 7 files changed, 43 insertions(+), 5 deletions(-) diff --git a/libraries/gl/src/gl/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp index b2c98e91d3..ddb93e0fa0 100644 --- a/libraries/gl/src/gl/GLHelpers.cpp +++ b/libraries/gl/src/gl/GLHelpers.cpp @@ -287,6 +287,7 @@ const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() { // Qt Quick may need a depth and stencil buffer. Always make sure these are available. format.setDepthBufferSize(DEFAULT_GL_DEPTH_BUFFER_BITS); format.setStencilBufferSize(DEFAULT_GL_STENCIL_BUFFER_BITS); + format.setColorSpace(QSurfaceFormat::ColorSpace::sRGBColorSpace); auto glversion = ::gl::getTargetVersion(); format.setMajorVersion(GL_GET_MAJOR_VERSION(glversion)); format.setMinorVersion(GL_GET_MINOR_VERSION(glversion)); diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h index 428c08e9f6..6fa7362e84 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h +++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h @@ -63,6 +63,7 @@ namespace scriptable { * @property {Mat4|string} texCoordTransform1 * @property {string} lightmapParams * @property {string} materialParams + * @property {string} opacityMode * @property {boolean} defaultFallthrough */ class ScriptableMaterial { @@ -94,7 +95,7 @@ namespace scriptable { QString lightMap; QString scatteringMap; std::array texCoordTransforms; - + QString opacityMode; bool defaultFallthrough; std::unordered_map propertyFallthroughs; // not actually exposed to script diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp index 45f8461a1a..a271affe49 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp @@ -420,6 +420,18 @@ namespace scriptable { obj.setProperty("opacityMap", material.opacityMap); } + + obj.setProperty("keys.isOpaque", material.key.isOpaque()); + obj.setProperty("keys.isOpacityMaskMap", material.key.isOpacityMaskMap()); + obj.setProperty("keys.isTexelOpaque", material.key.isTexelOpaque()); + obj.setProperty("keys.isSurfaceOpaque", material.key.isSurfaceOpaque()); + + if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_MASK_MAP_BIT)) { + obj.setProperty("opacityMapMode", FALLTHROUGH); + } else if (material.key.isGlossy()) { + obj.setProperty("opacityMapMode", material.opacityMode); + } + if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OCCLUSION_MAP_BIT)) { obj.setProperty("occlusionMap", FALLTHROUGH); } else if (!material.occlusionMap.isEmpty()) { diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp index e9cc7930ae..071272a382 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp @@ -41,6 +41,8 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const occlusionMap = material.occlusionMap; lightMap = material.lightMap; scatteringMap = material.scatteringMap; + opacityMode = material.opacityMode; + defaultFallthrough = material.defaultFallthrough; propertyFallthroughs = material.propertyFallthroughs; @@ -55,6 +57,9 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint name = material->getName().c_str(); model = material->getModel().c_str(); opacity = material->getOpacity(); + + opacityMode = (opacity < 1.0f ? "opacityVarAlpha" : "opaque"); + roughness = material->getRoughness(); metallic = material->getMetallic(); scattering = material->getScattering(); @@ -75,6 +80,8 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint albedoMap = map->getTextureSource()->getUrl().toString(); if (map->useAlphaChannel()) { opacityMap = albedoMap; + //opacityMode = (material->getKey().isOpacityMaskMap() ? "opacityMapAlphaMask" : "opacityMapAlphaBlend"); + opacityMode = (material->getKey().isOpacityMaskMap() ? "opacityMapAlphaMask" : "opacityMapAlphaBlend"); } } diff --git a/scripts/developer/utilities/render/materialInspector.js b/scripts/developer/utilities/render/materialInspector.js index 98d9f769fb..8a7d5ad7dd 100644 --- a/scripts/developer/utilities/render/materialInspector.js +++ b/scripts/developer/utilities/render/materialInspector.js @@ -128,7 +128,7 @@ function fromQml(message) { var SELECT_LIST = "luci_materialInspector_SelectionList"; Selection.enableListHighlight(SELECT_LIST, { - outlineUnoccludedColor: { red: 255, green: 255, blue: 255 } + outlineUnoccludedColor: { red: 125, green: 255, blue: 225 } }); function setSelectedObject(id, type) { Selection.clearSelectedItemsList(SELECT_LIST); diff --git a/tools/gpu-frame-player/src/RenderThread.cpp b/tools/gpu-frame-player/src/RenderThread.cpp index ff0d7630e5..27e76b5ad8 100644 --- a/tools/gpu-frame-player/src/RenderThread.cpp +++ b/tools/gpu-frame-player/src/RenderThread.cpp @@ -51,6 +51,12 @@ void RenderThread::initialize(QWindow* window) { _backend = _gpuContext->getBackend(); _context.doneCurrent(); _context.moveToThread(_thread); + + if (!_presentPipeline) { + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture); + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + _presentPipeline = gpu::Pipeline::create(program, state); + } #else auto size = window->size(); _extent = vk::Extent2D{ (uint32_t)size.width(), (uint32_t)size.height() }; @@ -169,15 +175,26 @@ void RenderThread::renderFrame(gpu::FramePointer& frame) { } #ifdef USE_GL + static gpu::BatchPointer batch = nullptr; + if (!batch) { + batch = std::make_shared(); + batch->setPipeline(_presentPipeline); + batch->setFramebuffer(nullptr); + batch->setResourceTexture(0, frame->framebuffer->getRenderBuffer(0)); + batch->setViewportTransform(ivec4(uvec2(0), ivec2(0.5 * fboSize.x, 0.5*fboSize.y))); + batch->draw(gpu::TRIANGLE_STRIP, 4); + } + _gpuContext->executeBatch(*batch); + //glDisable(GL_FRAMEBUFFER_SRGB); //glClear(GL_COLOR_BUFFER_BIT); - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); + /* glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBlitFramebuffer( 0, 0, fboSize.x, fboSize.y, 0, 0, windowSize.width(), windowSize.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST); - +*/ (void)CHECK_GL_ERROR(); _context.swapBuffers(); _context.doneCurrent(); diff --git a/tools/gpu-frame-player/src/RenderThread.h b/tools/gpu-frame-player/src/RenderThread.h index 09eef56623..b090e1737f 100644 --- a/tools/gpu-frame-player/src/RenderThread.h +++ b/tools/gpu-frame-player/src/RenderThread.h @@ -57,7 +57,7 @@ public: uint32_t _externalTexture{ 0 }; void move(const glm::vec3& v); glm::mat4 _correction; - + gpu::PipelinePointer _presentPipeline; void resize(const QSize& newSize); void setup() override; From 68b754fc0c20465be00dbe8006b6b7774b1a93dd Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 12 Sep 2019 17:01:16 -0700 Subject: [PATCH 02/21] Changes driven by the alpha mode --- .../src/graphics-scripting/Forward.h | 1 + .../GraphicsScriptingInterface.cpp | 6 +- .../graphics-scripting/ScriptableModel.cpp | 2 + libraries/graphics/src/graphics/Material.cpp | 25 +++++-- libraries/graphics/src/graphics/Material.h | 67 +++++++++++++++---- libraries/graphics/src/graphics/Material.slh | 10 +-- .../src/graphics/MaterialTextures.slh | 7 ++ .../render-utils/src/RenderPipelines.cpp | 1 + libraries/render-utils/src/model.slf | 18 +++-- 9 files changed, 103 insertions(+), 34 deletions(-) diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h index 6fa7362e84..c74c1c09bf 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h +++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h @@ -79,6 +79,7 @@ namespace scriptable { float roughness; float metallic; float scattering; + float alphaCutoff; bool unlit; glm::vec3 emissive; glm::vec3 albedo; diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp index a271affe49..02083af932 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp @@ -382,7 +382,8 @@ namespace scriptable { if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_VAL_BIT)) { obj.setProperty("scattering", FALLTHROUGH); - } else if (material.key.isScattering()) { + } + else if (material.key.isScattering()) { obj.setProperty("scattering", material.scattering); } @@ -428,8 +429,11 @@ namespace scriptable { if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_MASK_MAP_BIT)) { obj.setProperty("opacityMapMode", FALLTHROUGH); + obj.setProperty("alphaCutoff", FALLTHROUGH); } else if (material.key.isGlossy()) { obj.setProperty("opacityMapMode", material.opacityMode); + + obj.setProperty("alphaCutoff", material.alphaCutoff); } if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OCCLUSION_MAP_BIT)) { diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp index 071272a382..a81f17f254 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp @@ -26,6 +26,7 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const roughness = material.roughness; metallic = material.metallic; scattering = material.scattering; + alphaCutoff = material.alphaCutoff; unlit = material.unlit; emissive = material.emissive; albedo = material.albedo; @@ -63,6 +64,7 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint roughness = material->getRoughness(); metallic = material->getMetallic(); scattering = material->getScattering(); + alphaCutoff = material->getAlphaCutoff(); unlit = material->isUnlit(); emissive = material->getEmissive(); albedo = material->getAlbedo(); diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index 6be8ec5f68..d18ad4b74e 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -22,7 +22,8 @@ const float Material::DEFAULT_OPACITY { 1.0f }; const float Material::DEFAULT_ALBEDO { 0.5f }; const float Material::DEFAULT_METALLIC { 0.0f }; const float Material::DEFAULT_ROUGHNESS { 1.0f }; -const float Material::DEFAULT_SCATTERING { 0.0f }; +const float Material::DEFAULT_SCATTERING{ 0.0f }; +const float Material::DEFAULT_ALPHA_CUTOFF { 0.5f }; Material::Material() { for (int i = 0; i < NUM_TOTAL_FLAGS; i++) { @@ -40,6 +41,7 @@ Material::Material(const Material& material) : _roughness(material._roughness), _metallic(material._metallic), _scattering(material._scattering), + _alphaCutoff(material._alphaCutoff), _texcoordTransforms(material._texcoordTransforms), _lightmapParams(material._lightmapParams), _materialParams(material._materialParams), @@ -50,7 +52,7 @@ Material::Material(const Material& material) : } Material& Material::operator=(const Material& material) { - QMutexLocker locker(&_textureMapsMutex); + std::lock_guard locker(_textureMapsMutex); _name = material._name; _model = material._model; @@ -61,6 +63,7 @@ Material& Material::operator=(const Material& material) { _roughness = material._roughness; _metallic = material._metallic; _scattering = material._scattering; + _alphaCutoff = material._alphaCutoff; _texcoordTransforms = material._texcoordTransforms; _lightmapParams = material._lightmapParams; _materialParams = material._materialParams; @@ -109,8 +112,22 @@ void Material::setScattering(float scattering) { _scattering = scattering; } +void Material::setAlphaCutoff(float alphaCutoff) { + alphaCutoff = glm::clamp(alphaCutoff, 0.0f, 1.0f); + // _key.setAlphaCutoff(alphaCutoff != DEFAULT_ALPHA_CUTOFF); + _alphaCutoff = alphaCutoff; +} + +void Material::setAlphaMapMode(MaterialKey::AlphaMapMode alphaMode) { + _key.setAlphaMapMode(alphaMode); +} + +MaterialKey::AlphaMapMode Material::getAlphaMapMode() const { + return _key.getAlphaMapMode(); +} + void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) { - QMutexLocker locker(&_textureMapsMutex); + std::lock_guard locker(_textureMapsMutex); if (textureMap) { _key.setMapChannel(channel, true); @@ -166,7 +183,7 @@ void Material::resetOpacityMap() const { } const TextureMapPointer Material::getTextureMap(MapChannel channel) const { - QMutexLocker locker(&_textureMapsMutex); + std::lock_guard locker(_textureMapsMutex); auto result = _textureMaps.find(channel); if (result != _textureMaps.end()) { diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 25601c5743..500eab9a39 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -11,8 +11,7 @@ #ifndef hifi_model_Material_h #define hifi_model_Material_h -#include - +#include #include #include #include @@ -73,6 +72,12 @@ public: NUM_MAP_CHANNELS, }; + enum AlphaMapMode { + ALPHA_MAP_OPAQUE = 0, + ALPHA_MAP_MASK, + ALPHA_MAP_BLEND, + }; + // The signature is the Flags Flags _flags; @@ -104,6 +109,23 @@ public: Builder& withTranslucentMap() { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } Builder& withMaskMap() { _flags.set(OPACITY_MASK_MAP_BIT); return (*this); } + Builder& withAlphaMapMode(AlphaMapMode mode) { + switch (mode) { + case ALPHA_MAP_OPAQUE: + _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.reset(OPACITY_MASK_MAP_BIT); + break; + case ALPHA_MAP_MASK: + _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.set(OPACITY_MASK_MAP_BIT); + break; + case ALPHA_MAP_BLEND: + _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.reset(OPACITY_MASK_MAP_BIT); + break; + }; + return (*this); + } Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); } Builder& withOcclusionMap() { _flags.set(OCCLUSION_MAP_BIT); return (*this); } @@ -171,6 +193,25 @@ public: // Translucency and Opacity Heuristics are combining several flags: + void setAlphaMapMode(AlphaMapMode mode) { + switch (mode) { + case ALPHA_MAP_OPAQUE: + _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.reset(OPACITY_MASK_MAP_BIT); + break; + case ALPHA_MAP_MASK: + _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.set(OPACITY_MASK_MAP_BIT); + break; + case ALPHA_MAP_BLEND: + _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.reset(OPACITY_MASK_MAP_BIT); + break; + }; + } + AlphaMapMode getAlphaMapMode() const { return (_flags[OPACITY_MASK_MAP_BIT] ? ALPHA_MAP_MASK : (_flags[OPACITY_TRANSLUCENT_MAP_BIT] ? ALPHA_MAP_BLEND : ALPHA_MAP_OPAQUE)); } + + bool isTranslucent() const { return isTranslucentFactor() || isTranslucentMap(); } bool isOpaque() const { return !isTranslucent(); } bool isSurfaceOpaque() const { return isOpaque() && !isOpacityMaskMap(); } @@ -283,6 +324,13 @@ public: void setOpacity(float opacity); float getOpacity() const { return _opacity; } + void setAlphaMapMode(MaterialKey::AlphaMapMode alphaMode); + MaterialKey::AlphaMapMode getAlphaMapMode() const; + + static const float DEFAULT_ALPHA_CUTOFF; + void setAlphaCutoff(float alphaCutoff); + float getAlphaCutoff() const { return _alphaCutoff; } + void setUnlit(bool value); bool isUnlit() const { return _key.isUnlit(); } @@ -357,6 +405,7 @@ private: float _roughness { DEFAULT_ROUGHNESS }; float _metallic { DEFAULT_METALLIC }; float _scattering { DEFAULT_SCATTERING }; + float _alphaCutoff { DEFAULT_ALPHA_CUTOFF }; std::array _texcoordTransforms; glm::vec2 _lightmapParams { 0.0, 1.0 }; glm::vec2 _materialParams { 0.0, 1.0 }; @@ -365,7 +414,7 @@ private: bool _defaultFallthrough { false }; std::unordered_map _propertyFallthroughs { NUM_TOTAL_FLAGS }; - mutable QMutex _textureMapsMutex { QMutex::Recursive }; + mutable std::recursive_mutex _textureMapsMutex; }; typedef std::shared_ptr MaterialPointer; @@ -425,18 +474,8 @@ public: float _metallic { Material::DEFAULT_METALLIC }; // Not Metallic float _scattering { Material::DEFAULT_SCATTERING }; // Scattering info -#if defined(__clang__) - __attribute__((unused)) -#endif - glm::vec2 _spare { 0.0f }; // Padding - + float _alphaCutoff { Material::DEFAULT_ALPHA_CUTOFF }; // Alpha cutoff applyed when using alphaMa as Mask uint32_t _key { 0 }; // a copy of the materialKey -#if defined(__clang__) - __attribute__((unused)) -#endif - glm::vec3 _spare2 { 0.0f }; - - // for alignment beauty, Material size == Mat4x4 // Texture Coord Transform Array glm::mat4 _texcoordTransforms[Material::NUM_TEXCOORD_TRANSFORMS]; diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index dfd4a8eec4..8ebf66417c 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -49,8 +49,7 @@ struct TexMapArray { struct Material { vec4 _emissiveOpacity; vec4 _albedoRoughness; - vec4 _metallicScatteringSpare2; - vec4 _keySpare3; + vec4 _metallicScatteringAlphaCutoffKey; }; LAYOUT_STD140(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer { @@ -72,10 +71,11 @@ vec3 getMaterialAlbedo(Material m) { return m._albedoRoughness.rgb; } float getMaterialRoughness(Material m) { return m._albedoRoughness.a; } float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); } -float getMaterialMetallic(Material m) { return m._metallicScatteringSpare2.x; } -float getMaterialScattering(Material m) { return m._metallicScatteringSpare2.y; } +float getMaterialMetallic(Material m) { return m._metallicScatteringAlphaCutoffKey.x; } +float getMaterialScattering(Material m) { return m._metallicScatteringAlphaCutoffKey.y; } +float getMaterialAlphaCutoff(Material m) { return m._metallicScatteringAlphaCutoffKey.z; } -BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._keySpare3.x); } +BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._metallicScatteringAlphaCutoffKey.w); } const BITFIELD EMISSIVE_VAL_BIT = 0x00000001; const BITFIELD UNLIT_VAL_BIT = 0x00000002; diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index 278057b01a..93b90cc591 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -214,6 +214,13 @@ vec3 fetchLightMap(vec2 uv) { } <@endfunc@> +<@func evalMaterialOpacityMask(fetchedOpacity, materialAlphaCutoff, opacity)@> +{ + <$opacity$> = step(<$materialAlphaCutoff$>, <$fetchedOpacity$>); +} +<@endfunc@> + + <@func evalMaterialOpacity(fetchedOpacity, materialOpacity, matKey, opacity)@> { const float OPACITY_MASK_THRESHOLD = 0.5; diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index d0ebe167f9..14ceb4f9be 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -486,6 +486,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial schemaKey.setAlbedoMap(true); schemaKey.setOpacityMaskMap(material->getKey().isOpacityMaskMap()); schemaKey.setTranslucentMap(material->getKey().isTranslucentMap()); + schema._alphaCutoff = material->getAlphaCutoff(); } break; case graphics::MaterialKey::METALLIC_MAP_BIT: diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index 3e4711dac8..2d9cb6c654 100644 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -104,13 +104,12 @@ void main(void) { <@if HIFI_USE_TRANSLUCENT@> float opacity = getMaterialOpacity(mat) * _color.a; - <@else@> - float opacity = 1.0; - <@endif@> <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; - <@if HIFI_USE_TRANSLUCENT@> <$discardInvisible(opacity)$>; <@else@> + float cutoff = getMaterialAlphaCutoff(mat); + float opacity = 1.0; + <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>; <$discardTransparent(opacity)$>; <@endif@> @@ -156,14 +155,13 @@ void main(void) { <@if HIFI_USE_TRANSLUCENT@> float opacity = getMaterialOpacity(mat) * _color.a; - <@else@> - float opacity = 1.0; - <@endif@> <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; - <@if HIFI_USE_TRANSLUCENT@> - <$discardInvisible(opacity)$>; + <$discardInvisible(opacity)$>; <@else@> - <$discardTransparent(opacity)$>; + float cutoff = getMaterialAlphaCutoff(mat); + float opacity = 1.0; + <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>; + <$discardTransparent(opacity)$>; <@endif@> vec3 albedo = getMaterialAlbedo(mat); From 3ec812d5c3654837930baa75fa1e46d7a2766224 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 13 Sep 2019 18:45:16 -0700 Subject: [PATCH 03/21] Cleaner way maybe --- .../src/graphics-scripting/ScriptableModel.cpp | 5 +---- libraries/graphics/src/graphics/Material.cpp | 6 ++++++ libraries/graphics/src/graphics/Material.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp index a81f17f254..4f656d2d7d 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp @@ -59,8 +59,7 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint model = material->getModel().c_str(); opacity = material->getOpacity(); - opacityMode = (opacity < 1.0f ? "opacityVarAlpha" : "opaque"); - + opacityMode = QString(graphics::MaterialKey::getAlphaMapModeName(material->getAlphaMapMode()).c_str()); roughness = material->getRoughness(); metallic = material->getMetallic(); scattering = material->getScattering(); @@ -82,8 +81,6 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint albedoMap = map->getTextureSource()->getUrl().toString(); if (map->useAlphaChannel()) { opacityMap = albedoMap; - //opacityMode = (material->getKey().isOpacityMaskMap() ? "opacityMapAlphaMask" : "opacityMapAlphaBlend"); - opacityMode = (material->getKey().isOpacityMaskMap() ? "opacityMapAlphaMask" : "opacityMapAlphaBlend"); } } diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index d18ad4b74e..7524414947 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -25,6 +25,12 @@ const float Material::DEFAULT_ROUGHNESS { 1.0f }; const float Material::DEFAULT_SCATTERING{ 0.0f }; const float Material::DEFAULT_ALPHA_CUTOFF { 0.5f }; + +std::string MaterialKey::getAlphaMapModeName(AlphaMapMode mode) { + const std::string names[3] = { "ALPHA_MAP_OPAQUE", "ALPHA_MAP_MASK", "ALPHA_MAP_BLEND" }; + return names[mode]; +} + Material::Material() { for (int i = 0; i < NUM_TOTAL_FLAGS; i++) { _propertyFallthroughs[i] = false; diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 500eab9a39..2222d78b32 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -77,6 +77,7 @@ public: ALPHA_MAP_MASK, ALPHA_MAP_BLEND, }; + static std::string getAlphaMapModeName(AlphaMapMode mode); // The signature is the Flags Flags _flags; @@ -211,7 +212,6 @@ public: } AlphaMapMode getAlphaMapMode() const { return (_flags[OPACITY_MASK_MAP_BIT] ? ALPHA_MAP_MASK : (_flags[OPACITY_TRANSLUCENT_MAP_BIT] ? ALPHA_MAP_BLEND : ALPHA_MAP_OPAQUE)); } - bool isTranslucent() const { return isTranslucentFactor() || isTranslucentMap(); } bool isOpaque() const { return !isTranslucent(); } bool isSurfaceOpaque() const { return isOpaque() && !isOpacityMaskMap(); } From 18226e64f813be8bc3030249447b1dd99507df6e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 16 Sep 2019 18:06:43 -0700 Subject: [PATCH 04/21] Add a read lock where we think it s needed and banging my head on the problem --- libraries/entities-renderer/src/RenderableEntityItem.h | 9 --------- .../entities-renderer/src/RenderableModelEntityItem.cpp | 5 +++-- libraries/graphics/src/graphics/Material.h | 2 +- tools/gpu-frame-player/src/RenderThread.cpp | 4 +++- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 2697d30de4..d11f6dd6f4 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -108,15 +108,6 @@ protected: virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; } virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; } virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; } - - template - T withReadLockResult(const std::function& f) { - T result; - withReadLock([&] { - result = f(); - }); - return result; - } signals: void requestRenderUpdate(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 6314cc8ce4..a6325c243d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1431,12 +1431,13 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } } - if (!_texturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) { + bool currentTexturesLoaded = resultWithReadLock([&] { return _texturesLoaded; }); + if (!currentTexturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) { withWriteLock([&] { _texturesLoaded = true; }); model->updateRenderItems(); - } else if (!_texturesLoaded) { + } else if (!currentTexturesLoaded) { emit requestRenderUpdate(); } diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 2222d78b32..adfe53a962 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -210,7 +210,7 @@ public: break; }; } - AlphaMapMode getAlphaMapMode() const { return (_flags[OPACITY_MASK_MAP_BIT] ? ALPHA_MAP_MASK : (_flags[OPACITY_TRANSLUCENT_MAP_BIT] ? ALPHA_MAP_BLEND : ALPHA_MAP_OPAQUE)); } + AlphaMapMode getAlphaMapMode() const { return (isOpacityMaskMap() ? ALPHA_MAP_MASK : (isTranslucentMap() ? ALPHA_MAP_BLEND : ALPHA_MAP_OPAQUE)); } bool isTranslucent() const { return isTranslucentFactor() || isTranslucentMap(); } bool isOpaque() const { return !isTranslucent(); } diff --git a/tools/gpu-frame-player/src/RenderThread.cpp b/tools/gpu-frame-player/src/RenderThread.cpp index 27e76b5ad8..ef553e59fc 100644 --- a/tools/gpu-frame-player/src/RenderThread.cpp +++ b/tools/gpu-frame-player/src/RenderThread.cpp @@ -176,14 +176,16 @@ void RenderThread::renderFrame(gpu::FramePointer& frame) { #ifdef USE_GL static gpu::BatchPointer batch = nullptr; + float scale = 1.0; if (!batch) { batch = std::make_shared(); batch->setPipeline(_presentPipeline); batch->setFramebuffer(nullptr); batch->setResourceTexture(0, frame->framebuffer->getRenderBuffer(0)); - batch->setViewportTransform(ivec4(uvec2(0), ivec2(0.5 * fboSize.x, 0.5*fboSize.y))); + batch->setViewportTransform(ivec4(uvec2(0), ivec2(scale * fboSize.x, scale * fboSize.y))); batch->draw(gpu::TRIANGLE_STRIP, 4); } + glDisable(GL_FRAMEBUFFER_SRGB); _gpuContext->executeBatch(*batch); //glDisable(GL_FRAMEBUFFER_SRGB); From c0660329a378b9b7e1ab7d4abb62b5b5cd11fe6f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 17 Sep 2019 18:06:08 -0700 Subject: [PATCH 05/21] Exposing the REsource Caches through a bit of ui, adding MaterialCache to the family --- interface/src/Application.cpp | 6 +- .../src/RenderableModelEntityItem.cpp | 1 + .../MaterialCacheScriptingInterface.cpp | 17 +++ .../MaterialCacheScriptingInterface.h | 51 ++++++++ scripts/developer/utilities/cache/cash.js | 66 ++++++++++ scripts/developer/utilities/cache/cash.qml | 80 ++++++++++++ .../cache/cash/AnimationCacheInspector.qml | 20 +++ .../cache/cash/MaterialCacheInspector.qml | 20 +++ .../cache/cash/ModelCacheInspector.qml | 20 +++ .../developer/utilities/cache/cash/Page.js | 90 +++++++++++++ .../cache/cash/ResourceCacheInspector.qml | 122 ++++++++++++++++++ .../cache/cash/SoundCacheInspector.qml | 20 +++ .../cache/cash/TextureCacheInspector.qml | 20 +++ scripts/developer/utilities/cache/cash/qmldir | 6 + scripts/developer/utilities/lib/prop/qmldir | 1 + .../utilities/lib/prop/style/PiButton.qml | 32 +++++ 16 files changed, 571 insertions(+), 1 deletion(-) create mode 100644 libraries/material-networking/src/material-networking/MaterialCacheScriptingInterface.cpp create mode 100644 libraries/material-networking/src/material-networking/MaterialCacheScriptingInterface.h create mode 100644 scripts/developer/utilities/cache/cash.js create mode 100644 scripts/developer/utilities/cache/cash.qml create mode 100644 scripts/developer/utilities/cache/cash/AnimationCacheInspector.qml create mode 100644 scripts/developer/utilities/cache/cash/MaterialCacheInspector.qml create mode 100644 scripts/developer/utilities/cache/cash/ModelCacheInspector.qml create mode 100644 scripts/developer/utilities/cache/cash/Page.js create mode 100644 scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml create mode 100644 scripts/developer/utilities/cache/cash/SoundCacheInspector.qml create mode 100644 scripts/developer/utilities/cache/cash/TextureCacheInspector.qml create mode 100644 scripts/developer/utilities/cache/cash/qmldir create mode 100644 scripts/developer/utilities/lib/prop/style/PiButton.qml diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b719f26c68..be2519e4ea 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -105,8 +105,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -885,6 +885,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -2908,6 +2909,7 @@ Application::~Application() { DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); + DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); @@ -3433,6 +3435,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { // Caches surfaceContext->setContextProperty("AnimationCache", DependencyManager::get().data()); surfaceContext->setContextProperty("TextureCache", DependencyManager::get().data()); + surfaceContext->setContextProperty("MaterialCache", DependencyManager::get().data()); surfaceContext->setContextProperty("ModelCache", DependencyManager::get().data()); surfaceContext->setContextProperty("SoundCache", DependencyManager::get().data()); @@ -7563,6 +7566,7 @@ void Application::registerScriptEngineWithApplicationServices(const ScriptEngine // Caches scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get().data()); scriptEngine->registerGlobalObject("TextureCache", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("MaterialCache", DependencyManager::get().data()); scriptEngine->registerGlobalObject("ModelCache", DependencyManager::get().data()); scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get().data()); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index a6325c243d..a91d07947a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -41,6 +41,7 @@ void ModelEntityWrapper::setModel(const ModelPointer& model) { if (_model) { _needsInitialSimulation = true; } + } }); } diff --git a/libraries/material-networking/src/material-networking/MaterialCacheScriptingInterface.cpp b/libraries/material-networking/src/material-networking/MaterialCacheScriptingInterface.cpp new file mode 100644 index 0000000000..193d9b96ee --- /dev/null +++ b/libraries/material-networking/src/material-networking/MaterialCacheScriptingInterface.cpp @@ -0,0 +1,17 @@ +// +// MaterialCacheScriptingInterface.cpp +// libraries/mmodel-networking/src/model-networking +// +// Created by Sam Gateau on 17 September 2019. +// Copyright 2019 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 "MaterialCacheScriptingInterface.h" + +MaterialCacheScriptingInterface::MaterialCacheScriptingInterface() : + ScriptableResourceCache::ScriptableResourceCache(DependencyManager::get()) +{ } + diff --git a/libraries/material-networking/src/material-networking/MaterialCacheScriptingInterface.h b/libraries/material-networking/src/material-networking/MaterialCacheScriptingInterface.h new file mode 100644 index 0000000000..c619966a2a --- /dev/null +++ b/libraries/material-networking/src/material-networking/MaterialCacheScriptingInterface.h @@ -0,0 +1,51 @@ +// +// MaterialCacheScriptingInterface.h +// libraries/material-networking/src/material-networking +// +// Created by Sam Gateau on 17 September 2019. +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once + +#ifndef hifi_MaterialCacheScriptingInterface_h +#define hifi_MaterialCacheScriptingInterface_h + +#include + +#include + +#include "MaterialCache.h" + +class MaterialCacheScriptingInterface : public ScriptableResourceCache, public Dependency { + Q_OBJECT + + // Properties are copied over from ResourceCache (see ResourceCache.h for reason). + + /**jsdoc + * The TextureCache API manages texture cache resources. + * + * @namespace TextureCache + * + * @hifi-interface + * @hifi-client-entity + * @hifi-avatar + * + * @property {number} numTotal - Total number of total resources. Read-only. + * @property {number} numCached - Total number of cached resource. Read-only. + * @property {number} sizeTotal - Size in bytes of all resources. Read-only. + * @property {number} sizeCached - Size in bytes of all cached resources. Read-only. + * + * @borrows ResourceCache.getResourceList as getResourceList + * @borrows ResourceCache.updateTotalSize as updateTotalSize + * @borrows ResourceCache.prefetch as prefetch + * @borrows ResourceCache.dirty as dirty + */ + +public: + MaterialCacheScriptingInterface(); +}; + +#endif // hifi_MaterialCacheScriptingInterface_h diff --git a/scripts/developer/utilities/cache/cash.js b/scripts/developer/utilities/cache/cash.js new file mode 100644 index 0000000000..078cd84218 --- /dev/null +++ b/scripts/developer/utilities/cache/cash.js @@ -0,0 +1,66 @@ +"use strict"; +var Page = Script.require('./cash/Page.js'); + +function openView() { + //window.closed.connect(function() { Script.stop(); }); + + + var pages = new Pages(); + function fromQml(message) { + console.log(JSON.stringify(message)) + if (pages.open(message.method)) { + return; + } + } + + var cashWindow + function openCashWindow(window) { + if (cashWindow !== undefined) { + activeWindow.fromQml.disconnect(fromQml); + } + if (window !== undefined) { + window.fromQml.connect(fromQml); + } + cashWindow = window; + + + var onMousePressEvent = function (e) { + }; + Controller.mousePressEvent.connect(onMousePressEvent); + + var onMouseReleaseEvent = function () { + }; + Controller.mouseReleaseEvent.connect(onMouseReleaseEvent); + + var onMouseMoveEvent = function (e) { + }; + Controller.mouseMoveEvent.connect(onMouseMoveEvent); + } + + function closeCashWindow() { + if (cashWindow !== undefined) { + activeWindow.fromQml.disconnect(fromQml); + } + cashWindow = {}; + + Controller.mousePressEvent.disconnect(onMousePressEvent); + Controller.mouseReleaseEvent.disconnect(onMouseReleaseEvent); + Controller.mouseMoveEvent.disconnect(onMouseMoveEvent); + pages.clear(); + } + + pages.addPage('Cash', 'Cash', "../cash.qml", 300, 420, openCashWindow, closeCashWindow); + pages.addPage('openModelCacheInspector', 'Model Cache Inspector', "./ModelCacheInspector.qml", 300, 500); + pages.addPage('openMaterialCacheInspector', 'Material Cache Inspector', "./MaterialCacheInspector.qml", 300, 500); + pages.addPage('openTextureCacheInspector', 'Texture Cache Inspector', "./TextureCacheInspector.qml", 300, 500); + pages.addPage('openAnimationCacheInspector', 'Animation Cache Inspector', "./AnimationCacheInspector.qml", 300, 500); + pages.addPage('openSoundCacheInspector', 'Sound Cache Inspector', "./SoundCacheInspector.qml", 300, 500); + + pages.open('Cash'); + + + return pages; +} + + +openView(); diff --git a/scripts/developer/utilities/cache/cash.qml b/scripts/developer/utilities/cache/cash.qml new file mode 100644 index 0000000000..a6551f117e --- /dev/null +++ b/scripts/developer/utilities/cache/cash.qml @@ -0,0 +1,80 @@ +// +// cash.qml +// +// Created by Sam Gateau on 17/9/2019 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + +import controlsUit 1.0 as HifiControls + +import "../lib/prop" as Prop +import "cash" + +Rectangle { + anchors.fill: parent + id: root; + + Prop.Global { id: global;} + color: global.color + + ScrollView { + id: scrollView + anchors.fill: parent + contentWidth: parent.width + clip: true + + Column { + id: column + width: parent.width + Prop.PropFolderPanel { + label: "Cache Inspectors" + isUnfold: true + panelFrameData: Component { + Column { + Prop.PropButton { + text: "Model" + onClicked: { + sendToScript({method: "openModelCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Material" + onClicked: { + sendToScript({method: "openMaterialCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Texture" + onClicked: { + sendToScript({method: "openTextureCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Animation" + onClicked: { + sendToScript({method: "openAnimationCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Sound" + onClicked: { + sendToScript({method: "openSoundCacheInspector"}); + } + width:column.width + } + } + } + } + } + } +} \ No newline at end of file diff --git a/scripts/developer/utilities/cache/cash/AnimationCacheInspector.qml b/scripts/developer/utilities/cache/cash/AnimationCacheInspector.qml new file mode 100644 index 0000000000..1a9fc822fa --- /dev/null +++ b/scripts/developer/utilities/cache/cash/AnimationCacheInspector.qml @@ -0,0 +1,20 @@ +// +// AnimationCacheInspector.qml +// +// Created by Sam Gateau on 2019-09-17 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.7 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 + +import "../../lib/prop" as Prop + +ResourceCacheInspector { + id: root; + anchors.fill: parent.fill + cache: AnimationCache +} diff --git a/scripts/developer/utilities/cache/cash/MaterialCacheInspector.qml b/scripts/developer/utilities/cache/cash/MaterialCacheInspector.qml new file mode 100644 index 0000000000..fcdd0cbed0 --- /dev/null +++ b/scripts/developer/utilities/cache/cash/MaterialCacheInspector.qml @@ -0,0 +1,20 @@ +// +// MaterialCacheInspector.qml +// +// Created by Sam Gateau on 2019-09-17 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.7 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 + +import "../../lib/prop" as Prop + +ResourceCacheInspector { + id: root; + anchors.fill: parent.fill + cache: MaterialCache +} diff --git a/scripts/developer/utilities/cache/cash/ModelCacheInspector.qml b/scripts/developer/utilities/cache/cash/ModelCacheInspector.qml new file mode 100644 index 0000000000..10615b2632 --- /dev/null +++ b/scripts/developer/utilities/cache/cash/ModelCacheInspector.qml @@ -0,0 +1,20 @@ +// +// ModelCacheInspector.qml +// +// Created by Sam Gateau on 2019-09-17 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.7 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 + +import "../../lib/prop" as Prop + +ResourceCacheInspector { + id: root; + anchors.fill: parent.fill + cache: ModelCache +} diff --git a/scripts/developer/utilities/cache/cash/Page.js b/scripts/developer/utilities/cache/cash/Page.js new file mode 100644 index 0000000000..06c9704abf --- /dev/null +++ b/scripts/developer/utilities/cache/cash/Page.js @@ -0,0 +1,90 @@ +// +// Page.js +// +// Sam Gateau, created on 4/19/2019 +// Copyright 2019 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 +// +"use strict"; + +(function() { +function Page(title, qmlurl, width, height, onViewCreated, onViewClosed) { + this.title = title; + this.qml = qmlurl; + this.width = width; + this.height = height; + this.onViewCreated = onViewCreated; + this.onViewClosed = onViewClosed; + + this.window; + + print("Page: New Page:" + JSON.stringify(this)); +} + +Page.prototype.killView = function () { + print("Page: Kill window for page:" + JSON.stringify(this)); + if (this.window) { + print("Page: Kill window for page:" + this.title); + //this.window.closed.disconnect(function () { + // this.killView(); + //}); + this.window.close(); + this.window = false; + } +}; + +Page.prototype.createView = function () { + var that = this; + if (!this.window) { + print("Page: New window for page:" + this.title); + this.window = Desktop.createWindow(Script.resolvePath(this.qml), { + title: this.title, + presentationMode: Desktop.PresentationMode.NATIVE, + size: {x: this.width, y: this.height} + }); + this.onViewCreated(this.window); + this.window.closed.connect(function () { + that.killView(); + that.onViewClosed(); + }); + } +}; + + +Pages = function () { + this._pages = {}; +}; + +Pages.prototype.addPage = function (command, title, qmlurl, width, height, onViewCreated, onViewClosed) { + if (onViewCreated === undefined) { + // Workaround for bad linter + onViewCreated = function(window) {}; + } + if (onViewClosed === undefined) { + // Workaround for bad linter + onViewClosed = function() {}; + } + this._pages[command] = new Page(title, qmlurl, width, height, onViewCreated, onViewClosed); +}; + +Pages.prototype.open = function (command) { + print("Pages: command = " + command); + if (!this._pages[command]) { + print("Pages: unknown command = " + command); + return; + } + this._pages[command].createView(); +}; + +Pages.prototype.clear = function () { + for (var p in this._pages) { + print("Pages: kill page: " + p); + this._pages[p].killView(); + delete this._pages[p]; + } + this._pages = {}; +}; + +}()); diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml new file mode 100644 index 0000000000..a6b4c1df5d --- /dev/null +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -0,0 +1,122 @@ +// +// ResourceCacheInspector.qml +// +// Created by Sam Gateau on 2019-09-17 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.7 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 + +import "../../lib/prop" as Prop + +Item { + id: root; + anchors.fill: parent.fill + property var cache: {} + + function fromScript(message) { + switch (message.method) { + case "setJSON": + // jsonText.items = message.params.items; + break; + case "setItemList": + //console.log(message.params.items) + resouceItemsModel.resetItemList(message.params.items) + break; + case "resetItemList": + resetItemList() + break; + } + } + + Component.onCompleted: { + // if (cache !== undefined) { + resetItemList(); + // } + } + + function resetItemList() { + var theList = cache.getResourceList(); + resouceItemsModel.resetItemList(theList) + } + + ListModel { + id: resouceItemsModel + + function resetItemList(itemList) { + resouceItemsModel.clear() + for (var i in itemList) { + //resouceItemsModel.append({ "name": itemList[i]}) + resouceItemsModel.append({ "name": itemList[i].toString()}) + } + } + } + + Component { + id: resouceItemDelegate + Row { + id: itemRow + Prop.PropLabel { + text: model.name + } + } + } + + + Item { + id: header + + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + + + Prop.PropButton { + + anchors.left: parent.left + id: refresh + text: "Refresh" + onClicked: { + resetItemList() + } + } + + Prop.PropScalar { + id: totalCount + anchors.right: parent.right + label: "Count" + sourceValueVar: resouceItemsModel.count + integral: true + readOnly: true + } + + Prop.PropScalar { + id: totalCount + anchors.right: parent.right + label: "Count" + sourceValueVar: resouceItemsModel.count + integral: true + readOnly: true + } + + height: refresh.height + } + + + ScrollView { + anchors.top: header.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + clip: true + ListView { + id: listView + model: resouceItemsModel + delegate: resouceItemDelegate + } + } +} diff --git a/scripts/developer/utilities/cache/cash/SoundCacheInspector.qml b/scripts/developer/utilities/cache/cash/SoundCacheInspector.qml new file mode 100644 index 0000000000..2aef4efefd --- /dev/null +++ b/scripts/developer/utilities/cache/cash/SoundCacheInspector.qml @@ -0,0 +1,20 @@ +// +// SoundCacheInspector.qml +// +// Created by Sam Gateau on 2019-09-17 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.7 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 + +import "../../lib/prop" as Prop + +ResourceCacheInspector { + id: root; + anchors.fill: parent.fill + cache: SoundCache +} diff --git a/scripts/developer/utilities/cache/cash/TextureCacheInspector.qml b/scripts/developer/utilities/cache/cash/TextureCacheInspector.qml new file mode 100644 index 0000000000..a136ce6c47 --- /dev/null +++ b/scripts/developer/utilities/cache/cash/TextureCacheInspector.qml @@ -0,0 +1,20 @@ +// +// TextureCacheInspector.qml +// +// Created by Sam Gateau on 2019-09-17 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.7 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 + +import "../../lib/prop" as Prop + +ResourceCacheInspector { + id: root; + anchors.fill: parent.fill + cache: TextureCache +} diff --git a/scripts/developer/utilities/cache/cash/qmldir b/scripts/developer/utilities/cache/cash/qmldir new file mode 100644 index 0000000000..8793a6b8f5 --- /dev/null +++ b/scripts/developer/utilities/cache/cash/qmldir @@ -0,0 +1,6 @@ +ResourceCacheInspector 1.0 ResourceCacheInspector.qml +TextureCacheInspector 1.0 TextureCacheInspector.qml +MaterialCacheInspector 1.0 MaterialCacheInspector.qml +ModelCacheInspector 1.0 ModelCacheInspector.qml +AnimationCacheInspector 1.0 AnimationCacheInspector.qml +SoundCacheInspector 1.0 SoundCacheInspector.qml \ No newline at end of file diff --git a/scripts/developer/utilities/lib/prop/qmldir b/scripts/developer/utilities/lib/prop/qmldir index e09785846d..7d87c8a911 100644 --- a/scripts/developer/utilities/lib/prop/qmldir +++ b/scripts/developer/utilities/lib/prop/qmldir @@ -3,6 +3,7 @@ Global 1.0 style/Global.qml PropText 1.0 style/PiText.qml PropLabel 1.0 style/PiLabel.qml PropSplitter 1.0 style/PiSplitter.qml +PropButton 1.0 style/PiButton.qml PropComboBox 1.0 style/PiComboBox.qml PropCanvasIcon 1.0 style/PiCanvasIcon.qml PropCheckBox 1.0 style/PiCheckBox.qml diff --git a/scripts/developer/utilities/lib/prop/style/PiButton.qml b/scripts/developer/utilities/lib/prop/style/PiButton.qml new file mode 100644 index 0000000000..654d47e76d --- /dev/null +++ b/scripts/developer/utilities/lib/prop/style/PiButton.qml @@ -0,0 +1,32 @@ +// +// Prop/style/PiButton.qml +// +// Created by Sam Gateau on 17/09/2019 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.6 +import QtQuick.Controls 2.1 + +Button { + Global { id: global } + id: control + text: "" + spacing: 0 + + contentItem: PiText { + text: control.text + horizontalAlignment: Text.AlignHCenter + } + + background: Rectangle { + color: control.down ? global.colorBackHighlight : global.colorBackShadow + opacity: enabled ? 1 : 0.3 + border.color: control.down ? global.colorBorderHighight : (control.hovered ? global.colorBorderHighight : global.colorBorderLight) + border.width: global.valueBorderWidth + radius: global.valueBorderRadius + } +} \ No newline at end of file From a87db2636ccb80990d19a15780276aa6419413a9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 18 Sep 2019 18:25:42 -0700 Subject: [PATCH 06/21] SOme stuff workbetter --- libraries/networking/src/ResourceCache.cpp | 2 + libraries/networking/src/ResourceCache.h | 3 + libraries/render/src/render/EngineStats.cpp | 1 + libraries/render/src/render/EngineStats.h | 62 ++++--- scripts/developer/utilities/cache/cash.js | 2 +- scripts/developer/utilities/cache/cash.qml | 53 ++++++ .../cache/cash/AnimationCacheInspector.qml | 1 + .../cache/cash/MaterialCacheInspector.qml | 1 + .../cache/cash/ModelCacheInspector.qml | 1 + .../cache/cash/ResourceCacheInspector.qml | 156 +++++++++++------- .../cache/cash/SoundCacheInspector.qml | 1 + .../cache/cash/TextureCacheInspector.qml | 1 + .../developer/utilities/lib/prop/PropItem.qml | 8 +- .../utilities/lib/prop/PropScalar.qml | 5 +- 14 files changed, 195 insertions(+), 102 deletions(-) diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 88e6b14ec7..36daf7709c 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -148,6 +148,8 @@ void ResourceCacheSharedItems::clear() { ScriptableResourceCache::ScriptableResourceCache(QSharedPointer resourceCache) { _resourceCache = resourceCache; + connect(&(*_resourceCache), &ResourceCache::dirty, + this, &ScriptableResourceCache::dirty, Qt::DirectConnection); } QVariantList ScriptableResourceCache::getResourceList() { diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index e1f3098658..8026acb265 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -200,12 +200,15 @@ class ResourceCache : public QObject { Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty) Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) + Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) + public: size_t getNumTotalResources() const { return _numTotalResources; } size_t getSizeTotalResources() const { return _totalResourcesSize; } size_t getNumCachedResources() const { return _numUnusedResources; } size_t getSizeCachedResources() const { return _unusedResourcesSize; } + size_t getSizeCachedResources() const { return _unusedResourcesSize; } Q_INVOKABLE QVariantList getResourceList(); diff --git a/libraries/render/src/render/EngineStats.cpp b/libraries/render/src/render/EngineStats.cpp index ae1467ac0f..9f45f7e559 100644 --- a/libraries/render/src/render/EngineStats.cpp +++ b/libraries/render/src/render/EngineStats.cpp @@ -63,4 +63,5 @@ void EngineStats::run(const RenderContextPointer& renderContext) { config->frameSetPipelineCount = _gpuStats._PSNumSetPipelines; config->frameSetInputFormatCount = _gpuStats._ISNumFormatChanges; + config->emitDirty(); } diff --git a/libraries/render/src/render/EngineStats.h b/libraries/render/src/render/EngineStats.h index 3ccbd40715..9150e78f82 100644 --- a/libraries/render/src/render/EngineStats.h +++ b/libraries/render/src/render/EngineStats.h @@ -24,42 +24,42 @@ namespace render { class EngineStatsConfig : public Job::Config{ Q_OBJECT - Q_PROPERTY(quint32 bufferCPUCount MEMBER bufferCPUCount NOTIFY dirty) - Q_PROPERTY(quint32 bufferGPUCount MEMBER bufferGPUCount NOTIFY dirty) - Q_PROPERTY(qint64 bufferCPUMemSize MEMBER bufferCPUMemSize NOTIFY dirty) - Q_PROPERTY(qint64 bufferGPUMemSize MEMBER bufferGPUMemSize NOTIFY dirty) + Q_PROPERTY(quint32 bufferCPUCount MEMBER bufferCPUCount NOTIFY newStats) + Q_PROPERTY(quint32 bufferGPUCount MEMBER bufferGPUCount NOTIFY newStats) + Q_PROPERTY(qint64 bufferCPUMemSize MEMBER bufferCPUMemSize NOTIFY newStats) + Q_PROPERTY(qint64 bufferGPUMemSize MEMBER bufferGPUMemSize NOTIFY newStats) - Q_PROPERTY(quint32 textureCPUCount MEMBER textureCPUCount NOTIFY dirty) - Q_PROPERTY(quint32 textureGPUCount MEMBER textureGPUCount NOTIFY dirty) - Q_PROPERTY(quint32 textureResidentGPUCount MEMBER textureResidentGPUCount NOTIFY dirty) - Q_PROPERTY(quint32 textureFramebufferGPUCount MEMBER textureFramebufferGPUCount NOTIFY dirty) - Q_PROPERTY(quint32 textureResourceGPUCount MEMBER textureResourceGPUCount NOTIFY dirty) - Q_PROPERTY(quint32 textureExternalGPUCount MEMBER textureExternalGPUCount NOTIFY dirty) + Q_PROPERTY(quint32 textureCPUCount MEMBER textureCPUCount NOTIFY newStats) + Q_PROPERTY(quint32 textureGPUCount MEMBER textureGPUCount NOTIFY newStats) + Q_PROPERTY(quint32 textureResidentGPUCount MEMBER textureResidentGPUCount NOTIFY newStats) + Q_PROPERTY(quint32 textureFramebufferGPUCount MEMBER textureFramebufferGPUCount NOTIFY newStats) + Q_PROPERTY(quint32 textureResourceGPUCount MEMBER textureResourceGPUCount NOTIFY newStats) + Q_PROPERTY(quint32 textureExternalGPUCount MEMBER textureExternalGPUCount NOTIFY newStats) - Q_PROPERTY(qint64 textureCPUMemSize MEMBER textureCPUMemSize NOTIFY dirty) - Q_PROPERTY(qint64 textureGPUMemSize MEMBER textureGPUMemSize NOTIFY dirty) - Q_PROPERTY(qint64 textureResidentGPUMemSize MEMBER textureResidentGPUMemSize NOTIFY dirty) - Q_PROPERTY(qint64 textureFramebufferGPUMemSize MEMBER textureFramebufferGPUMemSize NOTIFY dirty) - Q_PROPERTY(qint64 textureResourceGPUMemSize MEMBER textureResourceGPUMemSize NOTIFY dirty) - Q_PROPERTY(qint64 textureExternalGPUMemSize MEMBER textureExternalGPUMemSize NOTIFY dirty) + Q_PROPERTY(qint64 textureCPUMemSize MEMBER textureCPUMemSize NOTIFY newStats) + Q_PROPERTY(qint64 textureGPUMemSize MEMBER textureGPUMemSize NOTIFY newStats) + Q_PROPERTY(qint64 textureResidentGPUMemSize MEMBER textureResidentGPUMemSize NOTIFY newStats) + Q_PROPERTY(qint64 textureFramebufferGPUMemSize MEMBER textureFramebufferGPUMemSize NOTIFY newStats) + Q_PROPERTY(qint64 textureResourceGPUMemSize MEMBER textureResourceGPUMemSize NOTIFY newStats) + Q_PROPERTY(qint64 textureExternalGPUMemSize MEMBER textureExternalGPUMemSize NOTIFY newStats) - Q_PROPERTY(quint32 texturePendingGPUTransferCount MEMBER texturePendingGPUTransferCount NOTIFY dirty) - Q_PROPERTY(qint64 texturePendingGPUTransferSize MEMBER texturePendingGPUTransferSize NOTIFY dirty) - Q_PROPERTY(qint64 textureResourcePopulatedGPUMemSize MEMBER textureResourcePopulatedGPUMemSize NOTIFY dirty) + Q_PROPERTY(quint32 texturePendingGPUTransferCount MEMBER texturePendingGPUTransferCount NOTIFY newStats) + Q_PROPERTY(qint64 texturePendingGPUTransferSize MEMBER texturePendingGPUTransferSize NOTIFY newStats) + Q_PROPERTY(qint64 textureResourcePopulatedGPUMemSize MEMBER textureResourcePopulatedGPUMemSize NOTIFY newStats) - Q_PROPERTY(quint32 frameAPIDrawcallCount MEMBER frameAPIDrawcallCount NOTIFY dirty) - Q_PROPERTY(quint32 frameDrawcallCount MEMBER frameDrawcallCount NOTIFY dirty) - Q_PROPERTY(quint32 frameDrawcallRate MEMBER frameDrawcallRate NOTIFY dirty) + Q_PROPERTY(quint32 frameAPIDrawcallCount MEMBER frameAPIDrawcallCount NOTIFY newStats) + Q_PROPERTY(quint32 frameDrawcallCount MEMBER frameDrawcallCount NOTIFY newStats) + Q_PROPERTY(quint32 frameDrawcallRate MEMBER frameDrawcallRate NOTIFY newStats) - Q_PROPERTY(quint32 frameTriangleCount MEMBER frameTriangleCount NOTIFY dirty) - Q_PROPERTY(quint32 frameTriangleRate MEMBER frameTriangleRate NOTIFY dirty) + Q_PROPERTY(quint32 frameTriangleCount MEMBER frameTriangleCount NOTIFY newStats) + Q_PROPERTY(quint32 frameTriangleRate MEMBER frameTriangleRate NOTIFY newStats) - Q_PROPERTY(quint32 frameTextureCount MEMBER frameTextureCount NOTIFY dirty) - Q_PROPERTY(quint32 frameTextureRate MEMBER frameTextureRate NOTIFY dirty) - Q_PROPERTY(quint64 frameTextureMemoryUsage MEMBER frameTextureMemoryUsage NOTIFY dirty) + Q_PROPERTY(quint32 frameTextureCount MEMBER frameTextureCount NOTIFY newStats) + Q_PROPERTY(quint32 frameTextureRate MEMBER frameTextureRate NOTIFY newStats) + Q_PROPERTY(quint64 frameTextureMemoryUsage MEMBER frameTextureMemoryUsage NOTIFY newStats) - Q_PROPERTY(quint32 frameSetPipelineCount MEMBER frameSetPipelineCount NOTIFY dirty) - Q_PROPERTY(quint32 frameSetInputFormatCount MEMBER frameSetInputFormatCount NOTIFY dirty) + Q_PROPERTY(quint32 frameSetPipelineCount MEMBER frameSetPipelineCount NOTIFY newStats) + Q_PROPERTY(quint32 frameSetInputFormatCount MEMBER frameSetInputFormatCount NOTIFY newStats) public: @@ -104,10 +104,8 @@ namespace render { - void emitDirty() { emit dirty(); } + void emitDirty() { emit newStats(); } - signals: - void dirty(); }; class EngineStats { diff --git a/scripts/developer/utilities/cache/cash.js b/scripts/developer/utilities/cache/cash.js index 078cd84218..b575b481c7 100644 --- a/scripts/developer/utilities/cache/cash.js +++ b/scripts/developer/utilities/cache/cash.js @@ -49,7 +49,7 @@ function openView() { pages.clear(); } - pages.addPage('Cash', 'Cash', "../cash.qml", 300, 420, openCashWindow, closeCashWindow); + pages.addPage('Cash', 'Cash', "../cash.qml", 300, 500, openCashWindow, closeCashWindow); pages.addPage('openModelCacheInspector', 'Model Cache Inspector', "./ModelCacheInspector.qml", 300, 500); pages.addPage('openMaterialCacheInspector', 'Material Cache Inspector', "./MaterialCacheInspector.qml", 300, 500); pages.addPage('openTextureCacheInspector', 'Texture Cache Inspector', "./TextureCacheInspector.qml", 300, 500); diff --git a/scripts/developer/utilities/cache/cash.qml b/scripts/developer/utilities/cache/cash.qml index a6551f117e..572fd481cb 100644 --- a/scripts/developer/utilities/cache/cash.qml +++ b/scripts/developer/utilities/cache/cash.qml @@ -15,6 +15,7 @@ import controlsUit 1.0 as HifiControls import "../lib/prop" as Prop import "cash" +import "../lib/plotperf" Rectangle { anchors.fill: parent @@ -32,6 +33,58 @@ Rectangle { Column { id: column width: parent.width + + Prop.PropFolderPanel { + label: "Stats" + isUnfold: true + panelFrameData: Component { Column { + PlotPerf { + title: "Resources" + height: 200 + valueScale: 1 + valueUnit: "" + plots: [ + { + object: TextureCache, + prop: "numTotal", + label: "Textures", + color: "#1AC567" + }, + { + object: TextureCache, + prop: "numCached", + label: "Textures Cached", + color: "#FEC567" + }, + { + object: ModelCache, + prop: "numTotal", + label: "Models", + color: "#FED959" + }, + { + object: ModelCache, + prop: "numCached", + label: "Models Cached", + color: "#FEFE59" + }, + { + object: MaterialCache, + prop: "numTotal", + label: "Materials", + color: "#00B4EF" + }, + { + object: MaterialCache, + prop: "numCached", + label: "Materials Cached", + color: "#FFB4EF" + } + ] + } + }} + } + Prop.PropFolderPanel { label: "Cache Inspectors" isUnfold: true diff --git a/scripts/developer/utilities/cache/cash/AnimationCacheInspector.qml b/scripts/developer/utilities/cache/cash/AnimationCacheInspector.qml index 1a9fc822fa..4ded44c2b1 100644 --- a/scripts/developer/utilities/cache/cash/AnimationCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/AnimationCacheInspector.qml @@ -17,4 +17,5 @@ ResourceCacheInspector { id: root; anchors.fill: parent.fill cache: AnimationCache + cacheResourceName: "Animation" } diff --git a/scripts/developer/utilities/cache/cash/MaterialCacheInspector.qml b/scripts/developer/utilities/cache/cash/MaterialCacheInspector.qml index fcdd0cbed0..160c47c946 100644 --- a/scripts/developer/utilities/cache/cash/MaterialCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/MaterialCacheInspector.qml @@ -17,4 +17,5 @@ ResourceCacheInspector { id: root; anchors.fill: parent.fill cache: MaterialCache + cacheResourceName: "Material" } diff --git a/scripts/developer/utilities/cache/cash/ModelCacheInspector.qml b/scripts/developer/utilities/cache/cash/ModelCacheInspector.qml index 10615b2632..017942dfc9 100644 --- a/scripts/developer/utilities/cache/cash/ModelCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ModelCacheInspector.qml @@ -17,4 +17,5 @@ ResourceCacheInspector { id: root; anchors.fill: parent.fill cache: ModelCache + cacheResourceName: "Model" } diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index a6b4c1df5d..a8eeee2d27 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -17,41 +17,104 @@ Item { id: root; anchors.fill: parent.fill property var cache: {} + property string cacheResourceName: "" function fromScript(message) { switch (message.method) { - case "setJSON": - // jsonText.items = message.params.items; - break; - case "setItemList": - //console.log(message.params.items) - resouceItemsModel.resetItemList(message.params.items) - break; case "resetItemList": - resetItemList() + resetItemListFromCache() break; } } Component.onCompleted: { - // if (cache !== undefined) { - resetItemList(); - // } + resetItemListFromCache(); } - function resetItemList() { - var theList = cache.getResourceList(); - resouceItemsModel.resetItemList(theList) + function fetchItemsList() { + var theList; + if (cache !== undefined) { + theList = cache.getResourceList(); + } else { + theList = [{"name": "ResourceCacheInspector.cache is undefined"}]; + } + return theList; } + function resetItemListFromCache() { + resourceItemsModel.resetItemList(fetchItemsList()) + } + function updateItemListFromCache() { + resourceItemsModel.updateItemList(fetchItemsList()) + } + + Column { + id: header + + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + + + /*Prop.PropButton { + anchors.left: parent.left + id: refresh + text: "Refresh" + onClicked: { + resetItemListFromCache() + } + }*/ + Item { + anchors.left: parent.left + anchors.right: parent.right + + Prop.PropScalar { + id: totalCount + anchors.left: parent.left + anchors.right: parent.horizontalCenter + label: "Count" + object: root.cache + property: "numTotal" + integral: true + readOnly: true + onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() } + } + Prop.PropScalar { + id: cachedCount + anchors.left: parent.horizontalCenter + anchors.right: parent.right + label: "Cached" + object: root.cache + property: "numCached" + integral: true + readOnly: true + onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() } + } + height: totalCount.height + } + } + + ListModel { - id: resouceItemsModel + id: resourceItemsModel + function packItemEntry(item) { + var some_uri = Qt.resolvedUrl(item) + + return { "name": item, "url": some_uri} + } + function resetItemList(itemList) { - resouceItemsModel.clear() + resourceItemsModel.clear() for (var i in itemList) { - //resouceItemsModel.append({ "name": itemList[i]}) - resouceItemsModel.append({ "name": itemList[i].toString()}) + resourceItemsModel.append(packItemEntry(itemList[i])) + } + } + + function updateItemList(itemList) { + resourceItemsModel.clear() + for (var i in itemList) { + resourceItemsModel.append(packItemEntry(itemList[i])) } } } @@ -60,53 +123,22 @@ Item { id: resouceItemDelegate Row { id: itemRow - Prop.PropLabel { - text: model.name + Prop.PropText { + text: model.index + width: 30 } + Prop.PropSplitter { + size:8 + } + Prop.PropLabel { + text: JSON.stringify(model.url) + } + /* Prop.PropLabel { + text: model.url + }*/ } } - - Item { - id: header - - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - - - Prop.PropButton { - - anchors.left: parent.left - id: refresh - text: "Refresh" - onClicked: { - resetItemList() - } - } - - Prop.PropScalar { - id: totalCount - anchors.right: parent.right - label: "Count" - sourceValueVar: resouceItemsModel.count - integral: true - readOnly: true - } - - Prop.PropScalar { - id: totalCount - anchors.right: parent.right - label: "Count" - sourceValueVar: resouceItemsModel.count - integral: true - readOnly: true - } - - height: refresh.height - } - - ScrollView { anchors.top: header.bottom anchors.bottom: parent.bottom @@ -115,7 +147,7 @@ Item { clip: true ListView { id: listView - model: resouceItemsModel + model: resourceItemsModel delegate: resouceItemDelegate } } diff --git a/scripts/developer/utilities/cache/cash/SoundCacheInspector.qml b/scripts/developer/utilities/cache/cash/SoundCacheInspector.qml index 2aef4efefd..26b043469e 100644 --- a/scripts/developer/utilities/cache/cash/SoundCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/SoundCacheInspector.qml @@ -17,4 +17,5 @@ ResourceCacheInspector { id: root; anchors.fill: parent.fill cache: SoundCache + cacheResourceName: "Sound" } diff --git a/scripts/developer/utilities/cache/cash/TextureCacheInspector.qml b/scripts/developer/utilities/cache/cash/TextureCacheInspector.qml index a136ce6c47..9bfd663a4e 100644 --- a/scripts/developer/utilities/cache/cash/TextureCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/TextureCacheInspector.qml @@ -17,4 +17,5 @@ ResourceCacheInspector { id: root; anchors.fill: parent.fill cache: TextureCache + cacheResourceName: "Texture" } diff --git a/scripts/developer/utilities/lib/prop/PropItem.qml b/scripts/developer/utilities/lib/prop/PropItem.qml index 6d2f4c11ad..fe2364b59a 100644 --- a/scripts/developer/utilities/lib/prop/PropItem.qml +++ b/scripts/developer/utilities/lib/prop/PropItem.qml @@ -24,11 +24,11 @@ Item { // By default, these just go get or set the value from the object[property] // function defaultGet() { var v = root.object[root.property]; return v; } + // function defaultGet() { return root.object[root.property]; } function defaultSet(value) { root.object[root.property] = value; } - // function defaultSetReadOnly(value) { log ( "read only " + property + ", NOT setting to " + value); } - // function defaultSetReadOnly(value) {} - // property var valueVarSetter: (root.readOnly ? defaultSetReadOnly : defaultSet) - property var valueVarSetter: defaultSet + function defaultSetReadOnly(value) {} + + property var valueVarSetter: (readOnly ? defaultSetReadOnly : defaultSet) property var valueVarGetter: defaultGet // PropItem is stretching horizontally accross its parent diff --git a/scripts/developer/utilities/lib/prop/PropScalar.qml b/scripts/developer/utilities/lib/prop/PropScalar.qml index ce89342997..3776f5c4bc 100644 --- a/scripts/developer/utilities/lib/prop/PropScalar.qml +++ b/scripts/developer/utilities/lib/prop/PropScalar.qml @@ -32,9 +32,7 @@ PropItem { property var sourceValueVar: root.valueVarGetter() function applyValueVarFromWidgets(value) { - if (!root.readOnly) { - root.valueVarSetter(value) - } + root.valueVarSetter(value) } PropLabel { @@ -58,6 +56,7 @@ PropItem { MouseArea{ id: mousearea + enabled: !root.readOnly anchors.fill: parent onDoubleClicked: { sliderControl.visible = !sliderControl.visible } } From ee5de175eb028d3b02e6f2b57997361827d1c7de Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 19 Sep 2019 16:56:55 -0700 Subject: [PATCH 07/21] Better monitoring of the resource loading in flights --- libraries/networking/src/ResourceCache.cpp | 15 +- libraries/networking/src/ResourceCache.h | 19 ++- scripts/developer/utilities/cache/cash.qml | 139 +++++++++++----- .../cache/cash/ResourceCacheInspector.qml | 155 ++++++++++++++---- .../utilities/lib/jet/qml/TaskListView.qml | 12 +- 5 files changed, 252 insertions(+), 88 deletions(-) diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 36daf7709c..d29b4daf2f 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -325,7 +325,11 @@ QVariantList ResourceCache::getResourceList() { BLOCKING_INVOKE_METHOD(this, "getResourceList", Q_RETURN_ARG(QVariantList, list)); } else { - auto resources = _resources.uniqueKeys(); + QList resources; + { + QReadLocker locker(&_resourcesLock); + resources = _resources.uniqueKeys(); + } list.reserve(resources.size()); for (auto& resource : resources) { list << resource; @@ -379,6 +383,7 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& } if (!resource) { + _numLoadingResources++; resource = createResource(url); resource->setExtra(extra); resource->setExtraHash(extraHash); @@ -386,6 +391,7 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& resource->setCache(this); resource->moveToThread(qApp->thread()); connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize); + connect(resource.data(), &Resource::finished, this, &ResourceCache::decreaseNumLoading); { QWriteLocker locker(&_resourcesLock); _resources[url].insert(extraHash, resource); @@ -513,6 +519,11 @@ void ResourceCache::updateTotalSize(const qint64& deltaSize) { emit dirty(); } +void ResourceCache::decreaseNumLoading() { + _numLoadingResources--; + emit dirty(); +} + QList> ResourceCache::getLoadingRequests() { return DependencyManager::get()->getLoadingRequests(); } @@ -530,7 +541,7 @@ bool ResourceCache::attemptRequest(QSharedPointer resource) { auto sharedItems = DependencyManager::get(); if (sharedItems->appendRequest(resource)) { - resource->makeRequest(); + resource->makeRequest(); return true; } return false; diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 8026acb265..f7af951d44 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -201,6 +201,7 @@ class ResourceCache : public QObject { Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) + Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty) public: @@ -208,10 +209,13 @@ public: size_t getSizeTotalResources() const { return _totalResourcesSize; } size_t getNumCachedResources() const { return _numUnusedResources; } size_t getSizeCachedResources() const { return _unusedResourcesSize; } - size_t getSizeCachedResources() const { return _unusedResourcesSize; } + size_t getNumPendingResources() const { return _numPendingResources; } + size_t getNumLoadingResources() const { return _numLoadingResources; } Q_INVOKABLE QVariantList getResourceList(); + Q_INVOKABLE void decreaseNumLoading(); + static void setRequestLimit(uint32_t limit); static uint32_t getRequestLimit() { return DependencyManager::get()->getRequestLimit(); } @@ -292,6 +296,8 @@ private: std::atomic _numTotalResources { 0 }; std::atomic _totalResourcesSize { 0 }; + std::atomic _numPendingResources{ 0 }; + std::atomic _numLoadingResources{ 0 }; // Cached resources QMap> _unusedResources; @@ -320,6 +326,12 @@ class ScriptableResourceCache : public QObject { Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty) Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) + Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty) + Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) + + Q_PROPERTY(size_t numGlobalQueriesPending READ getNumGlobalQueriesPending NOTIFY dirty) + Q_PROPERTY(size_t numGlobalQueriesLoading READ getNumGlobalQueriesLoading NOTIFY dirty) + public: ScriptableResourceCache(QSharedPointer resourceCache); @@ -393,6 +405,11 @@ private: size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); } size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); } size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); } + size_t getNumPendingResources() const { return _resourceCache->getNumPendingResources(); } + size_t getNumLoadingResources() const { return _resourceCache->getNumLoadingResources(); } + + size_t getNumGlobalQueriesPending() const { return ResourceCache::getLoadingRequestCount(); } + size_t getNumGlobalQueriesLoading() const { return ResourceCache::getPendingRequestCount(); } }; /// Base class for resources. diff --git a/scripts/developer/utilities/cache/cash.qml b/scripts/developer/utilities/cache/cash.qml index 572fd481cb..e143a82e62 100644 --- a/scripts/developer/utilities/cache/cash.qml +++ b/scripts/developer/utilities/cache/cash.qml @@ -34,6 +34,99 @@ Rectangle { id: column width: parent.width + Prop.PropFolderPanel { + label: "Resource Queries Inspector" + isUnfold: true + panelFrameData: Component { + Column { + PlotPerf { + title: "Global Queries" + height: 80 + valueScale: 1 + valueUnit: "" + plots: [ + { + object: ModelCache, + prop: "numGlobalQueriesPending", + label: "Pending", + color: "#1AC567" + }, + { + object: ModelCache, + prop: "numGlobalQueriesLoading", + label: "Loading", + color: "#FEC567" + }, + { + object: ModelCache, + prop: "numLoading", + label: "Model Loading", + color: "#C5FE67" + } + ] + } + } + } + } + + Prop.PropFolderPanel { + label: "Cache Inspectors" + isUnfold: true + panelFrameData: Component { + Column { + Prop.PropButton { + text: "Model" + onClicked: { + sendToScript({method: "openModelCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Material" + onClicked: { + sendToScript({method: "openMaterialCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Texture" + onClicked: { + sendToScript({method: "openTextureCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Animation" + onClicked: { + sendToScript({method: "openAnimationCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Sound" + onClicked: { + sendToScript({method: "openSoundCacheInspector"}); + } + width:column.width + } + + Prop.PropScalar { + label: "Texture Loading" + object: TextureCache + property: "numLoading" + integral: true + readOnly: true + } + Prop.PropScalar { + label: "Model Loading" + object: ModelCache + property: "numLoading" + integral: true + readOnly: true + } + } + } + } Prop.PropFolderPanel { label: "Stats" isUnfold: true @@ -81,51 +174,7 @@ Rectangle { color: "#FFB4EF" } ] - } - }} - } - - Prop.PropFolderPanel { - label: "Cache Inspectors" - isUnfold: true - panelFrameData: Component { - Column { - Prop.PropButton { - text: "Model" - onClicked: { - sendToScript({method: "openModelCacheInspector"}); - } - width:column.width - } - Prop.PropButton { - text: "Material" - onClicked: { - sendToScript({method: "openMaterialCacheInspector"}); - } - width:column.width - } - Prop.PropButton { - text: "Texture" - onClicked: { - sendToScript({method: "openTextureCacheInspector"}); - } - width:column.width - } - Prop.PropButton { - text: "Animation" - onClicked: { - sendToScript({method: "openAnimationCacheInspector"}); - } - width:column.width - } - Prop.PropButton { - text: "Sound" - onClicked: { - sendToScript({method: "openSoundCacheInspector"}); - } - width:column.width - } - } + }} } } } diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index a8eeee2d27..159773b06e 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -7,7 +7,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.7 +import QtQuick 2.12 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 @@ -36,18 +36,39 @@ Item { if (cache !== undefined) { theList = cache.getResourceList(); } else { - theList = [{"name": "ResourceCacheInspector.cache is undefined"}]; + theList = ["ResourceCacheInspector.cache is undefined"]; } - return theList; + var theListString = new Array(theList.length) + for (var i in theList) { + theListString[i] = (theList[i].toString()) + } + return theListString; } function resetItemListFromCache() { - resourceItemsModel.resetItemList(fetchItemsList()) + resetItemList(fetchItemsList()) } - function updateItemListFromCache() { - resourceItemsModel.updateItemList(fetchItemsList()) + + property var needFreshList : false + + function updateItemListFromCache() { + needFreshList = true } + Timer { + interval: 1000; running: true; repeat: true + onTriggered: pullFreshValues() + } + + function pullFreshValues() { + if (needFreshList) { + console.log("Updating " + cacheResourceName + "cache list") + updateItemList(fetchItemsList()) + needFreshList = false + } + } + + Column { id: header @@ -77,7 +98,7 @@ Item { property: "numTotal" integral: true readOnly: true - onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() } + onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;*/updateItemListFromCache() } } Prop.PropScalar { id: cachedCount @@ -88,7 +109,7 @@ Item { property: "numCached" integral: true readOnly: true - onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() } + onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumCached Value Changed!!!!");*/updateItemListFromCache() } } height: totalCount.height } @@ -97,26 +118,81 @@ Item { ListModel { id: resourceItemsModel - - function packItemEntry(item) { - var some_uri = Qt.resolvedUrl(item) - - return { "name": item, "url": some_uri} + } + property var currentItemsList: new Array(); + + function packItemEntry(item) { + var entry = { "name": "", "root": "", "path": "", "base": "", "url": item} + if (item.length > 0) { + var rootPos = item.search("://") + entry.root = item.substring(0, rootPos) + if (rootPos >= 0) rootPos += 3 + entry.path = item.substring(rootPos, item.length) + var splitted = entry.path.split('/') + entry.name = splitted[splitted.length - 1] + entry.base = splitted[0] } - - function resetItemList(itemList) { - resourceItemsModel.clear() - for (var i in itemList) { - resourceItemsModel.append(packItemEntry(itemList[i])) - } + return entry + } + + function resetItemList(itemList) { + currentItemsList = [] + resourceItemsModel.clear() + for (var i in itemList) { + var item = itemList[i] + currentItemsList.push(item) + resourceItemsModel.append(packItemEntry(item)) + } + } + + function updateItemList(newItemList) { + resetItemList(newItemList) +/* + var nextListLength = (currentItemList.length < newItemList.length ? newItemList.length : currentItemList.length ) + var nextList = new Array(nextListLength) + + var addedList = [] + var removedList = [] + var movedList = [] + + for (var i in currentItemList) { + var item = currentItemList[i] + var foundPos = newItemList.findIndex(item) + if (foundPos == i) { + newList[i] = item + newItemList[i] = 0 + } else if (foundPos == -1) { + removedList.push(i) + } else { + movedList.push([i,foundPos]) + } } - function updateItemList(itemList) { - resourceItemsModel.clear() - for (var i in itemList) { - resourceItemsModel.append(packItemEntry(itemList[i])) - } + for (var i in newItemList) { + var item = newItemList[i] + if (item != 0) { + var foundPos = currentItemList.findIndex(item) + if (foundPos == -1) { + addedList.push(item) + } + } } + + + for (var i in itemList) { + newList[i] = itemList[i] + } + + + + +*/ + /*currentItemsList.clear() + resourceItemsModel.clear() + for (var i in itemList) { + currentItemsList.append(itemList[i].toString()) + resourceItemsModel.append(packItemEntry(currentItemsList[i])) + } */ } Component { @@ -131,24 +207,35 @@ Item { size:8 } Prop.PropLabel { - text: JSON.stringify(model.url) + text: model.root + width: 30 } - /* Prop.PropLabel { - text: model.url - }*/ + Prop.PropSplitter { + size:8 + } + Prop.PropLabel { + text: model.base + width: 60 + } + Prop.PropSplitter { + size:8 + } + Prop.PropLabel { + text: model.name + } + } } - ScrollView { + ListView { anchors.top: header.bottom anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right clip: true - ListView { - id: listView - model: resourceItemsModel - delegate: resouceItemDelegate - } + + id: listView + model: resourceItemsModel + delegate: resouceItemDelegate } } diff --git a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml index e2576fe783..a935163bd9 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml @@ -91,12 +91,12 @@ Rectangle { } } - Original.ScrollView { + ListView { anchors.fill: parent - ListView { - id: theView - model: jobsModel - delegate: objRecursiveDelegate - } + + id: theView + model: jobsModel + delegate: objRecursiveDelegate } + } \ No newline at end of file From 4480d56433a25c0f35a6b5f6b803533167f44ce1 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 20 Sep 2019 19:00:03 -0700 Subject: [PATCH 08/21] Rendering just the overlay layer and improving the resoruceCache inspector to sort --- interface/src/graphics/GraphicsEngine.cpp | 23 +- libraries/networking/src/ResourceCache.cpp | 10 +- libraries/networking/src/ResourceCache.h | 8 +- .../cache/cash/ResourceCacheInspector.qml | 232 +++++++++++------- 4 files changed, 178 insertions(+), 95 deletions(-) diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp index 53c8bd7c18..98ad7c0ad7 100644 --- a/interface/src/graphics/GraphicsEngine.cpp +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -240,7 +240,7 @@ void GraphicsEngine::render_performFrame() { renderArgs._context->setStereoViews(stereoEyeOffsets); } } - + bool renderScene = true; gpu::FramebufferPointer finalFramebuffer; QSize finalFramebufferSize; { @@ -277,13 +277,32 @@ void GraphicsEngine::render_performFrame() { qApp->getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld); } - { + + if (renderScene) { PROFILE_RANGE(render, "/runRenderFrame"); renderArgs._hudOperator = displayPlugin->getHUDOperator(); renderArgs._hudTexture = qApp->getApplicationOverlay().getOverlayTexture(); renderArgs._takingSnapshot = qApp->takeSnapshotOperators(snapshotOperators); renderArgs._blitFramebuffer = finalFramebuffer; render_runRenderFrame(&renderArgs); + } else { + // Instead of clearing, drawing the splash screen background (that looks like the default skybox) + gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) { + batch.setFramebuffer(finalFramebuffer); + batch.enableSkybox(true); + batch.enableStereo(isStereo); + batch.clearDepthStencilFramebuffer(1.0, 0); + batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); + _splashScreen->render(batch, viewFrustum, renderArgs._renderMethod == RenderArgs::RenderMethod::FORWARD); + }); + + // THen just use the HUD operator of thedisplay plugin + gpu::doInBatch("drawHUD", renderArgs._context, [&](gpu::Batch& batch) { + batch.setFramebuffer(finalFramebuffer); + // TODO we should do more transform setup here just like in "REnderHUDLayerTask.cpp CompositeHUD job if we wanted to support stereo + displayPlugin->getHUDOperator()(batch, qApp->getApplicationOverlay().getOverlayTexture()); + }); + // And voila } } diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index d29b4daf2f..f8d5ecf28e 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -383,7 +383,6 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& } if (!resource) { - _numLoadingResources++; resource = createResource(url); resource->setExtra(extra); resource->setExtraHash(extraHash); @@ -391,7 +390,6 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& resource->setCache(this); resource->moveToThread(qApp->thread()); connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize); - connect(resource.data(), &Resource::finished, this, &ResourceCache::decreaseNumLoading); { QWriteLocker locker(&_resourcesLock); _resources[url].insert(extraHash, resource); @@ -518,10 +516,12 @@ void ResourceCache::updateTotalSize(const qint64& deltaSize) { emit dirty(); } - -void ResourceCache::decreaseNumLoading() { + +void ResourceCache::incrementNumLoading() { + _numLoadingResources++; +} +void ResourceCache::decrementNumLoading() { _numLoadingResources--; - emit dirty(); } QList> ResourceCache::getLoadingRequests() { diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index f7af951d44..b9b339644e 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -201,7 +201,6 @@ class ResourceCache : public QObject { Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) - Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty) public: @@ -209,12 +208,12 @@ public: size_t getSizeTotalResources() const { return _totalResourcesSize; } size_t getNumCachedResources() const { return _numUnusedResources; } size_t getSizeCachedResources() const { return _unusedResourcesSize; } - size_t getNumPendingResources() const { return _numPendingResources; } size_t getNumLoadingResources() const { return _numLoadingResources; } Q_INVOKABLE QVariantList getResourceList(); - Q_INVOKABLE void decreaseNumLoading(); + Q_INVOKABLE void incrementNumLoading(); + Q_INVOKABLE void decrementNumLoading(); static void setRequestLimit(uint32_t limit); static uint32_t getRequestLimit() { return DependencyManager::get()->getRequestLimit(); } @@ -296,7 +295,6 @@ private: std::atomic _numTotalResources { 0 }; std::atomic _totalResourcesSize { 0 }; - std::atomic _numPendingResources{ 0 }; std::atomic _numLoadingResources{ 0 }; // Cached resources @@ -326,7 +324,6 @@ class ScriptableResourceCache : public QObject { Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty) Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) - Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty) Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) Q_PROPERTY(size_t numGlobalQueriesPending READ getNumGlobalQueriesPending NOTIFY dirty) @@ -405,7 +402,6 @@ private: size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); } size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); } size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); } - size_t getNumPendingResources() const { return _resourceCache->getNumPendingResources(); } size_t getNumLoadingResources() const { return _resourceCache->getNumLoadingResources(); } size_t getNumGlobalQueriesPending() const { return ResourceCache::getLoadingRequestCount(); } diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index 159773b06e..a597ca3ec1 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -10,11 +10,14 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 +import QtQml.Models 2.12 import "../../lib/prop" as Prop Item { id: root; + Prop.Global { id: global } + anchors.fill: parent.fill property var cache: {} property string cacheResourceName: "" @@ -68,6 +71,9 @@ Item { } } + property var itemFields: ['name', 'root', 'base', 'path', 'index'] + property var itemFieldsVisibility: {'name': true, 'root': false, 'base':false, 'path':false, 'index':false} + Column { id: header @@ -88,6 +94,7 @@ Item { Item { anchors.left: parent.left anchors.right: parent.right + height: totalCount.height Prop.PropScalar { id: totalCount @@ -111,14 +118,150 @@ Item { readOnly: true onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumCached Value Changed!!!!");*/updateItemListFromCache() } } - height: totalCount.height + } + + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + height: orderSelector.height + + Prop.PropComboBox { + anchors.left: parent.left + id: orderSelector + model: [ "name", "base", "root" ] + property var selectedIndex: currentIndex + } + + Prop.PropCheckBox { + id: showName + text: 'name' + checked: itemFieldsVisibility['name'] + } + Prop.PropCheckBox { + id: showRoot + text: 'root' + checked: itemFieldsVisibility['root'] + } + Prop.PropCheckBox { + id: showBase + text: 'base' + checked: itemFieldsVisibility['base'] + } } } - ListModel { - id: resourceItemsModel + Component { + id: resouceItemDelegate + MouseArea { + id: dragArea + property bool held: false + anchors { left: parent.left; right: parent.right } + height: item.height + onPressed: {held = true} + onReleased: {held = false} + + Rectangle { + id: item + width: parent.width + height: global.slimHeight + color: dragArea.held ? global.colorBackHighlight : (model.index % 2 ? global.colorBackShadow : global.colorBack) + Row { + id: itemRow + anchors.verticalCenter : parent.verticalCenter + Prop.PropText { + id: itemIndex + text: model.index + width: 30 + } + Prop.PropSplitter { + visible: showRoot.checked + size:8 + } + Prop.PropLabel { + visible: showRoot.checked + text: model.root + width: 30 + } + Prop.PropSplitter { + visible: showBase.checked + size:8 + } + Prop.PropLabel { + visible: showBase.checked + text: model.base + width: 60 + } + Prop.PropSplitter { + visible: showName.checked + size:8 + } + Prop.PropLabel { + visible: showName.checked + text: model.name + } + } + } + + } } + DelegateModel { + id: visualModel + + model: ListModel {} + + property var lessThan: [ + function(left, right) { return left.name < right.name }, + function(left, right) { return left.base < right.base }, + function(left, right) { return left.root < right.root } + ] + + property int sortOrder: orderSelector.selectedIndex + onSortOrderChanged: items.setGroups(0, items.count, "unsorted") + + function insertPosition(lessThan, item) { + var lower = 0 + var upper = items.count + while (lower < upper) { + var middle = Math.floor(lower + (upper - lower) / 2) + var result = lessThan(item.model, items.get(middle).model); + if (result) { + upper = middle + } else { + lower = middle + 1 + } + } + return lower + } + + function sort(lessThan) { + while (unsortedItems.count > 0) { + var item = unsortedItems.get(0) + var index = insertPosition(lessThan, item) + + item.groups = "items" + items.move(item.itemsIndex, index) + } + } + + items.includeByDefault: false + groups: DelegateModelGroup { + id: unsortedItems + name: "unsorted" + + includeByDefault: true + onChanged: { + if (visualModel.sortOrder == visualModel.lessThan.length) + setGroups(0, count, "items") + else + visualModel.sort(visualModel.lessThan[visualModel.sortOrder]) + } + } + + + delegate: resouceItemDelegate + } + property alias resourceItemsModel: visualModel.model property var currentItemsList: new Array(); function packItemEntry(item) { @@ -135,6 +278,7 @@ Item { return entry } + function resetItemList(itemList) { currentItemsList = [] resourceItemsModel.clear() @@ -146,86 +290,11 @@ Item { } function updateItemList(newItemList) { - resetItemList(newItemList) -/* - var nextListLength = (currentItemList.length < newItemList.length ? newItemList.length : currentItemList.length ) - var nextList = new Array(nextListLength) - - var addedList = [] - var removedList = [] - var movedList = [] - - for (var i in currentItemList) { - var item = currentItemList[i] - var foundPos = newItemList.findIndex(item) - if (foundPos == i) { - newList[i] = item - newItemList[i] = 0 - } else if (foundPos == -1) { - removedList.push(i) - } else { - movedList.push([i,foundPos]) - } - } - - for (var i in newItemList) { - var item = newItemList[i] - if (item != 0) { - var foundPos = currentItemList.findIndex(item) - if (foundPos == -1) { - addedList.push(item) - } - } - } - - - for (var i in itemList) { - newList[i] = itemList[i] - } - - - - -*/ - /*currentItemsList.clear() - resourceItemsModel.clear() - for (var i in itemList) { - currentItemsList.append(itemList[i].toString()) - resourceItemsModel.append(packItemEntry(currentItemsList[i])) - } */ + resetItemList(newItemList) } - Component { - id: resouceItemDelegate - Row { - id: itemRow - Prop.PropText { - text: model.index - width: 30 - } - Prop.PropSplitter { - size:8 - } - Prop.PropLabel { - text: model.root - width: 30 - } - Prop.PropSplitter { - size:8 - } - Prop.PropLabel { - text: model.base - width: 60 - } - Prop.PropSplitter { - size:8 - } - Prop.PropLabel { - text: model.name - } - } - } + ListView { anchors.top: header.bottom @@ -235,7 +304,6 @@ Item { clip: true id: listView - model: resourceItemsModel - delegate: resouceItemDelegate + model: visualModel } } From 3e17c1007a106df9751284491da1df1bb19ca1b0 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 23 Sep 2019 18:14:45 -0700 Subject: [PATCH 09/21] understanding the delegateModelGroup mechanism... --- .../cache/cash/ResourceCacheInspector.qml | 156 ++++++++++++------ 1 file changed, 103 insertions(+), 53 deletions(-) diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index a597ca3ec1..71dc2f7d24 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -71,9 +71,8 @@ Item { } } - property var itemFields: ['name', 'root', 'base', 'path', 'index'] - property var itemFieldsVisibility: {'name': true, 'root': false, 'base':false, 'path':false, 'index':false} - + property var itemFields: ['index', 'name', 'scheme', 'host', 'pathDir', 'url'] + Column { id: header @@ -120,7 +119,7 @@ Item { } } - RowLayout { + Item { anchors.left: parent.left anchors.right: parent.right height: orderSelector.height @@ -128,29 +127,25 @@ Item { Prop.PropComboBox { anchors.left: parent.left id: orderSelector - model: [ "name", "base", "root" ] + model: itemFields property var selectedIndex: currentIndex + + property var isSchemeVisible: (currentIndex == 2) + property var isHostVisible: (currentIndex == 3) + property var isPathDirVisible: (currentIndex == 4) + property var isURLVisible: (currentIndex == 5) } - Prop.PropCheckBox { - id: showName - text: 'name' - checked: itemFieldsVisibility['name'] - } - Prop.PropCheckBox { - id: showRoot - text: 'root' - checked: itemFieldsVisibility['root'] - } - Prop.PropCheckBox { - id: showBase - text: 'base' - checked: itemFieldsVisibility['base'] - } + /* Prop.PropCheckBox { + anchors.left: orderSelector.right + id: listQRC + checked: true + text: "list qrc" + }*/ + } } - Component { id: resouceItemDelegate MouseArea { @@ -175,50 +170,70 @@ Item { width: 30 } Prop.PropSplitter { - visible: showRoot.checked + visible: orderSelector.isSchemeVisible size:8 } Prop.PropLabel { - visible: showRoot.checked - text: model.root + visible: orderSelector.isSchemeVisible + text: model.scheme width: 30 } Prop.PropSplitter { - visible: showBase.checked + visible: orderSelector.isHostVisible size:8 } Prop.PropLabel { - visible: showBase.checked - text: model.base - width: 60 + visible: orderSelector.isHostVisible + text: model.host + width: 150 } Prop.PropSplitter { - visible: showName.checked + visible: orderSelector.isPathDirVisible size:8 } Prop.PropLabel { - visible: showName.checked + visible: orderSelector.isPathDirVisible + text: model.pathDir + } + Prop.PropSplitter { + size:8 + } + Prop.PropLabel { + visible: !orderSelector.isURLVisible text: model.name } + Prop.PropLabel { + visible: orderSelector.isURLVisible + text: model.url + } } } } } + + // ['index', 'name', 'scheme', 'host', 'pathDir', 'url'] DelegateModel { id: visualModel model: ListModel {} + property var filterQRC: function(item) { return item.scheme == "qrc" } property var lessThan: [ + function(left, right) { return left.index < right.index }, function(left, right) { return left.name < right.name }, - function(left, right) { return left.base < right.base }, - function(left, right) { return left.root < right.root } + function(left, right) { return left.scheme < right.scheme }, + function(left, right) { return left.host < right.host }, + function(left, right) { return left.pathDir < right.pathDir }, + function(left, right) { return left.url < right.url } ] property int sortOrder: orderSelector.selectedIndex onSortOrderChanged: items.setGroups(0, items.count, "unsorted") + property bool listQRCChecked: listQRC.checked + onListQRCCheckedChanged: items.setGroups(0, items.count, "unsorted") + function insertPosition(lessThan, item) { var lower = 0 var upper = items.count @@ -237,26 +252,35 @@ Item { function sort(lessThan) { while (unsortedItems.count > 0) { var item = unsortedItems.get(0) + // var doHide = (!listQRCChecked && filterQRC(item.model)) + var index = insertPosition(lessThan, item) item.groups = "items" - items.move(item.itemsIndex, index) + // if (doHide) { + // item.inItems = false; + // } else { + // item.inItems = true; + items.move(item.itemsIndex, index) + // } } } items.includeByDefault: false - groups: DelegateModelGroup { - id: unsortedItems - name: "unsorted" + groups: + DelegateModelGroup { + id: unsortedItems + name: "unsorted" - includeByDefault: true - onChanged: { - if (visualModel.sortOrder == visualModel.lessThan.length) - setGroups(0, count, "items") - else - visualModel.sort(visualModel.lessThan[visualModel.sortOrder]) + includeByDefault: true + onChanged: { + if (visualModel.sortOrder == visualModel.lessThan.length) + setGroups(0, count, "items") + else + visualModel.sort(visualModel.lessThan[visualModel.sortOrder]) + } } - } + delegate: resouceItemDelegate @@ -264,16 +288,42 @@ Item { property alias resourceItemsModel: visualModel.model property var currentItemsList: new Array(); - function packItemEntry(item) { - var entry = { "name": "", "root": "", "path": "", "base": "", "url": item} + function packItemEntry(item, index) { + var entry = { "index": index, "name": "", "scheme": "", "host": "", "pathDir": "", "url": item} if (item.length > 0) { - var rootPos = item.search("://") - entry.root = item.substring(0, rootPos) - if (rootPos >= 0) rootPos += 3 - entry.path = item.substring(rootPos, item.length) - var splitted = entry.path.split('/') - entry.name = splitted[splitted.length - 1] - entry.base = splitted[0] + // Detect scheme: + var schemePos = item.search(":") + entry.scheme = item.substring(0, schemePos) + if (schemePos < 0) schemePos = 0 + else schemePos += 1 + + // path pos is probably after schemePos + var pathPos = schemePos + + // try to detect //userinfo@host:port + var token = item.substr(schemePos, 2); + if (token.search("//") == 0) { + pathPos += 2 + } + item = item.substring(pathPos, item.length) + // item is now everything after scheme:[//] + var splitted = item.split('/') + + // odd ball, the rest of the url has no other'/' ? + // in theory this means it s just the host info ? + // we are assuming that path ALWAYS starts with a slash + entry.host = splitted[0] + + if (splitted.length > 1) { + entry.name = splitted[splitted.length - 1] + + // if splitted is longer than 2 then there should be a path dir + if (splitted.length > 2) { + for (var i = 1; i < splitted.length - 1; i++) { + entry.pathDir += '/' + splitted[i] + } + } + } } return entry } @@ -285,7 +335,7 @@ Item { for (var i in itemList) { var item = itemList[i] currentItemsList.push(item) - resourceItemsModel.append(packItemEntry(item)) + resourceItemsModel.append(packItemEntry(item, currentItemsList.length -1)) } } From d940e705648114c8878c14ecb3d84cfdeb13fe54 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 24 Sep 2019 00:31:16 -0700 Subject: [PATCH 10/21] Adding a proper SortFilterModel --- .../cache/cash/ResourceCacheInspector.qml | 221 +++++++----------- .../utilities/cache/cash/SortFilterModel.qml | 118 ++++++++++ 2 files changed, 205 insertions(+), 134 deletions(-) create mode 100644 scripts/developer/utilities/cache/cash/SortFilterModel.qml diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index 71dc2f7d24..badc6e6754 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -59,7 +59,7 @@ Item { } Timer { - interval: 1000; running: true; repeat: true + interval: 2000; running: true; repeat: true onTriggered: pullFreshValues() } @@ -70,7 +70,65 @@ Item { needFreshList = false } } - + + property alias resourceItemsModel: visualModel.model + property var currentItemsList: new Array(); + + function packItemEntry(item, index) { + var entry = { "index": index, "name": "", "scheme": "", "host": "", "pathDir": "", "url": item} + if (item.length > 0) { + // Detect scheme: + var schemePos = item.search(":") + entry.scheme = item.substring(0, schemePos) + if (schemePos < 0) schemePos = 0 + else schemePos += 1 + + // path pos is probably after schemePos + var pathPos = schemePos + + // try to detect //userinfo@host:port + var token = item.substr(schemePos, 2); + if (token.search("//") == 0) { + pathPos += 2 + } + item = item.substring(pathPos, item.length) + // item is now everything after scheme:[//] + var splitted = item.split('/') + + // odd ball, the rest of the url has no other'/' ? + // in theory this means it s just the host info ? + // we are assuming that path ALWAYS starts with a slash + entry.host = splitted[0] + + if (splitted.length > 1) { + entry.name = splitted[splitted.length - 1] + + // if splitted is longer than 2 then there should be a path dir + if (splitted.length > 2) { + for (var i = 1; i < splitted.length - 1; i++) { + entry.pathDir += '/' + splitted[i] + } + } + } + } + return entry + } + + + function resetItemList(itemList) { + currentItemsList = [] + resourceItemsModel.clear() + for (var i in itemList) { + var item = itemList[i] + currentItemsList.push(item) + resourceItemsModel.append(packItemEntry(item, currentItemsList.length -1)) + } + } + + function updateItemList(newItemList) { + resetItemList(newItemList) + } + property var itemFields: ['index', 'name', 'scheme', 'host', 'pathDir', 'url'] @@ -81,15 +139,6 @@ Item { anchors.left: parent.left anchors.right: parent.right - - /*Prop.PropButton { - anchors.left: parent.left - id: refresh - text: "Refresh" - onClicked: { - resetItemListFromCache() - } - }*/ Item { anchors.left: parent.left anchors.right: parent.right @@ -104,7 +153,7 @@ Item { property: "numTotal" integral: true readOnly: true - onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;*/updateItemListFromCache() } + onSourceValueVarChanged: { updateItemListFromCache() } } Prop.PropScalar { id: cachedCount @@ -115,7 +164,7 @@ Item { property: "numCached" integral: true readOnly: true - onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumCached Value Changed!!!!");*/updateItemListFromCache() } + onSourceValueVarChanged: { updateItemListFromCache() } } } @@ -128,6 +177,7 @@ Item { anchors.left: parent.left id: orderSelector model: itemFields + currentIndex: 1 property var selectedIndex: currentIndex property var isSchemeVisible: (currentIndex == 2) @@ -136,12 +186,19 @@ Item { property var isURLVisible: (currentIndex == 5) } - /* Prop.PropCheckBox { + Prop.PropCheckBox { anchors.left: orderSelector.right id: listQRC - checked: true + checked: false text: "list qrc" - }*/ + } + + TextField { + anchors.left: listQRC.right + id: nameFilter + placeholderText: qsTr("Search by name...") + Layout.fillWidth: true + } } } @@ -212,139 +269,35 @@ Item { } } - // ['index', 'name', 'scheme', 'host', 'pathDir', 'url'] - DelegateModel { + SortFilterModel { id: visualModel - model: ListModel {} - property var filterQRC: function(item) { return item.scheme == "qrc" } - property var lessThan: [ + property int sortOrder: orderSelector.selectedIndex + + property var lessThanArray: [ function(left, right) { return left.index < right.index }, function(left, right) { return left.name < right.name }, function(left, right) { return left.scheme < right.scheme }, function(left, right) { return left.host < right.host }, function(left, right) { return left.pathDir < right.pathDir }, function(left, right) { return left.url < right.url } - ] + ]; + lessThan: lessThanArray[sortOrder] - property int sortOrder: orderSelector.selectedIndex - onSortOrderChanged: items.setGroups(0, items.count, "unsorted") - - property bool listQRCChecked: listQRC.checked - onListQRCCheckedChanged: items.setGroups(0, items.count, "unsorted") - - function insertPosition(lessThan, item) { - var lower = 0 - var upper = items.count - while (lower < upper) { - var middle = Math.floor(lower + (upper - lower) / 2) - var result = lessThan(item.model, items.get(middle).model); - if (result) { - upper = middle - } else { - lower = middle + 1 - } - } - return lower - } - - function sort(lessThan) { - while (unsortedItems.count > 0) { - var item = unsortedItems.get(0) - // var doHide = (!listQRCChecked && filterQRC(item.model)) - - var index = insertPosition(lessThan, item) - - item.groups = "items" - // if (doHide) { - // item.inItems = false; - // } else { - // item.inItems = true; - items.move(item.itemsIndex, index) - // } - } - } - - items.includeByDefault: false - groups: - DelegateModelGroup { - id: unsortedItems - name: "unsorted" - - includeByDefault: true - onChanged: { - if (visualModel.sortOrder == visualModel.lessThan.length) - setGroups(0, count, "items") - else - visualModel.sort(visualModel.lessThan[visualModel.sortOrder]) - } - } + property int listQRCChecked: listQRC.checked + property int textFilter: nameFilter.text + property var acceptItemArray: [ + function(item) { return item.scheme != "qrc" }, + // function(item) { return true } + function(item) { return (item.name.search(textFilter) >= 0) } + ] + acceptItem: acceptItemArray[0 + listQRCChecked] delegate: resouceItemDelegate } - property alias resourceItemsModel: visualModel.model - property var currentItemsList: new Array(); - - function packItemEntry(item, index) { - var entry = { "index": index, "name": "", "scheme": "", "host": "", "pathDir": "", "url": item} - if (item.length > 0) { - // Detect scheme: - var schemePos = item.search(":") - entry.scheme = item.substring(0, schemePos) - if (schemePos < 0) schemePos = 0 - else schemePos += 1 - - // path pos is probably after schemePos - var pathPos = schemePos - - // try to detect //userinfo@host:port - var token = item.substr(schemePos, 2); - if (token.search("//") == 0) { - pathPos += 2 - } - item = item.substring(pathPos, item.length) - // item is now everything after scheme:[//] - var splitted = item.split('/') - - // odd ball, the rest of the url has no other'/' ? - // in theory this means it s just the host info ? - // we are assuming that path ALWAYS starts with a slash - entry.host = splitted[0] - - if (splitted.length > 1) { - entry.name = splitted[splitted.length - 1] - - // if splitted is longer than 2 then there should be a path dir - if (splitted.length > 2) { - for (var i = 1; i < splitted.length - 1; i++) { - entry.pathDir += '/' + splitted[i] - } - } - } - } - return entry - } - - - function resetItemList(itemList) { - currentItemsList = [] - resourceItemsModel.clear() - for (var i in itemList) { - var item = itemList[i] - currentItemsList.push(item) - resourceItemsModel.append(packItemEntry(item, currentItemsList.length -1)) - } - } - - function updateItemList(newItemList) { - resetItemList(newItemList) - } - - - ListView { anchors.top: header.bottom diff --git a/scripts/developer/utilities/cache/cash/SortFilterModel.qml b/scripts/developer/utilities/cache/cash/SortFilterModel.qml new file mode 100644 index 0000000000..a4a9c3f6a3 --- /dev/null +++ b/scripts/developer/utilities/cache/cash/SortFilterModel.qml @@ -0,0 +1,118 @@ +import QtQuick 2.9 +import QtQml.Models 2.3 + +DelegateModel { + id: delegateModel + + property var lessThan: function(left, right) { return true; } + property var acceptItem: function(item) { return true; } +/* + function insertPosition(lessThan, item) { + var lower = 0 + var upper = items.count + while (lower < upper) { + var middle = Math.floor(lower + (upper - lower) / 2) + var result = lessThan(item.model, items.get(middle).model); + if (result) { + upper = middle + } else { + lower = middle + 1 + } + } + return lower + } + + function sort(lessThan) { + while (unsortedItems.count > 0) { + var item = unsortedItems.get(0) + + var index = insertPosition(lessThan, item) + + item.groups = "items" + items.move(item.itemsIndex, index) + } + } +*/ + function insertPosition(lessThanFunctor, item) { + var lower = 0 + var upper = visibleItems.count + while (lower < upper) { + var middle = Math.floor(lower + (upper - lower) / 2) + var result = lessThanFunctor(item.model, visibleItems.get(middle).model); + if (result) { + upper = middle + } else { + lower = middle + 1 + } + } + return lower + } + + function sort(lessThanFunctor, acceptItemFunctor) { + while (unsortedItems.count > 0) { + var item = unsortedItems.get(0) + + if (acceptItemFunctor(item.model)) { + var index = insertPosition(lessThanFunctor, item) + + item.groups = ["items","visible"] + visibleItems.move(item.visibleIndex, index) + } else { + item.groups = ["items"] + } + } + } + + function update() { + if (items.count > 0) { + items.setGroups(0, items.count, ["items","unsorted"]); + } + + sort(lessThan, acceptItem) + /* + // Step 1: Filter items + var visible = []; + for (var i = 0; i < items.count; ++i) { + var item = items.get(i); + if (filterAcceptsItem(item.model)) { + visible.push(item); + } + } + + // Step 2: Sort the list of visible items + visible.sort(function(a, b) { + return lessThan(a.model, b.model) ? -1 : 1; + }); + + // Step 3: Add all items to the visible group: + for (i = 0; i < visible.length; ++i) { + item = visible[i]; + item.inVisible = true; + if (item.visibleIndex !== i) { + visibleItems.move(item.visibleIndex, i, 1); + } + } + */ + } + + items.onChanged: update() + onLessThanChanged: update() + onAcceptItemChanged: update() + + groups: [ + DelegateModelGroup { + id: visibleItems + + name: "visible" + includeByDefault: false + }, + DelegateModelGroup { + id: unsortedItems + + name: "unsorted" + includeByDefault: false + } + ] + + filterOnGroup: "visible" +} \ No newline at end of file From 8aaa5deb11cc2961ea7d3299f447707f3beaa0f9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 24 Sep 2019 12:37:01 -0700 Subject: [PATCH 11/21] Clean up the sort and filter system --- .../cache/cash/ResourceCacheInspector.qml | 84 ++++++++++++------- .../developer/utilities/lib/prop/PropEnum.qml | 1 + scripts/developer/utilities/lib/prop/qmldir | 1 + .../utilities/lib/prop/style/PiComboBox.qml | 6 +- .../utilities/lib/prop/style/PiTextField.qml | 31 +++++++ 5 files changed, 88 insertions(+), 35 deletions(-) create mode 100644 scripts/developer/utilities/lib/prop/style/PiTextField.qml diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index badc6e6754..9b1ab907f9 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -74,8 +74,8 @@ Item { property alias resourceItemsModel: visualModel.model property var currentItemsList: new Array(); - function packItemEntry(item, index) { - var entry = { "index": index, "name": "", "scheme": "", "host": "", "pathDir": "", "url": item} + function packItemEntry(item, identifier) { + var entry = { "identifier": identifier, "name": "", "scheme": "", "host": "", "pathDir": "", "url": item} if (item.length > 0) { // Detect scheme: var schemePos = item.search(":") @@ -129,7 +129,7 @@ Item { resetItemList(newItemList) } - property var itemFields: ['index', 'name', 'scheme', 'host', 'pathDir', 'url'] + property var itemFields: ['identifier', 'name', 'scheme', 'host', 'pathDir', 'url'] Column { @@ -138,6 +138,7 @@ Item { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right + margin: global.horizontalMargin Item { anchors.left: parent.left @@ -167,40 +168,49 @@ Item { onSourceValueVarChanged: { updateItemListFromCache() } } } - Item { anchors.left: parent.left anchors.right: parent.right height: orderSelector.height - Prop.PropComboBox { + Prop.PropText { anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + width: 50 + id: orderSelectorLabel + text: "Sort by" + horizontalAlignment: Text.AlignHCenter + } + Prop.PropComboBox { + anchors.left: orderSelectorLabel.right + width: 80 id: orderSelector model: itemFields currentIndex: 1 - property var selectedIndex: currentIndex - - property var isSchemeVisible: (currentIndex == 2) - property var isHostVisible: (currentIndex == 3) - property var isPathDirVisible: (currentIndex == 4) - property var isURLVisible: (currentIndex == 5) + + property var isSchemeVisible: (currentIndex == 2 || filterFieldSelector.currentIndex == 2) + property var isHostVisible: (currentIndex == 3 || filterFieldSelector.currentIndex == 3) + property var isPathDirVisible: (currentIndex == 4 || filterFieldSelector.currentIndex == 4) + property var isURLVisible: (currentIndex == 5 || filterFieldSelector.currentIndex == 5) } - Prop.PropCheckBox { + Prop.PropTextField { anchors.left: orderSelector.right - id: listQRC - checked: false - text: "list qrc" - } - - TextField { - anchors.left: listQRC.right + anchors.right: filterFieldSelector.left id: nameFilter - placeholderText: qsTr("Search by name...") + placeholderText: qsTr("Filter by " + itemFields[filterFieldSelector.currentIndex] + "...") Layout.fillWidth: true } - + Prop.PropComboBox { + anchors.right: parent.right + id: filterFieldSelector + model: itemFields + currentIndex: 1 + width: 80 + opacity: (nameFilter.text.length > 0) ? 1.0 : 0.5 + } } + Prop.Prop } Component { @@ -217,13 +227,13 @@ Item { id: item width: parent.width height: global.slimHeight - color: dragArea.held ? global.colorBackHighlight : (model.index % 2 ? global.colorBackShadow : global.colorBack) + color: dragArea.held ? global.colorBackHighlight : (model.identifier % 2 ? global.colorBackShadow : global.colorBack) Row { id: itemRow anchors.verticalCenter : parent.verticalCenter Prop.PropText { - id: itemIndex - text: model.index + id: itemIdentifier + text: model.identifier width: 30 } Prop.PropSplitter { @@ -273,7 +283,7 @@ Item { id: visualModel model: ListModel {} - property int sortOrder: orderSelector.selectedIndex + property int sortOrder: orderSelector.currentIndex property var lessThanArray: [ function(left, right) { return left.index < right.index }, @@ -285,17 +295,27 @@ Item { ]; lessThan: lessThanArray[sortOrder] - property int listQRCChecked: listQRC.checked - property int textFilter: nameFilter.text + property int filterField: filterFieldSelector.currentIndex + onFilterFieldChanged: { refreshFilter() } + property var textFilter: nameFilter.text + onTextFilterChanged: { refreshFilter() } + function filterToken(itemWord, token) { return (itemWord.search(token) > -1) } property var acceptItemArray: [ - function(item) { return item.scheme != "qrc" }, - // function(item) { return true } - function(item) { return (item.name.search(textFilter) >= 0) } + function(item) { return true }, + function(item) { return filterToken(item.identifier.toString(), textFilter) }, + function(item) { return filterToken(item.name, textFilter) }, + function(item) { return filterToken(item.scheme, textFilter) }, + function(item) { return filterToken(item.host, textFilter) }, + function(item) { return filterToken(item.pathDir, textFilter) }, + function(item) { return filterToken(item.url, textFilter) } ] - acceptItem: acceptItemArray[0 + listQRCChecked] - + function refreshFilter() { + console.log("refreshFilter! token = " + textFilter + " field = " + filterField) + acceptItem = acceptItemArray[(textFilter.length != 0) * + (1 + filterField)] + } + delegate: resouceItemDelegate } diff --git a/scripts/developer/utilities/lib/prop/PropEnum.qml b/scripts/developer/utilities/lib/prop/PropEnum.qml index 2268b21e34..97c385281d 100644 --- a/scripts/developer/utilities/lib/prop/PropEnum.qml +++ b/scripts/developer/utilities/lib/prop/PropEnum.qml @@ -16,6 +16,7 @@ PropItem { id: root property alias enums : valueCombo.model + property alias currentIndex : valueCombo.currentIndex PropComboBox { id: valueCombo diff --git a/scripts/developer/utilities/lib/prop/qmldir b/scripts/developer/utilities/lib/prop/qmldir index 7d87c8a911..99e721fb33 100644 --- a/scripts/developer/utilities/lib/prop/qmldir +++ b/scripts/developer/utilities/lib/prop/qmldir @@ -1,6 +1,7 @@ Module Prop Global 1.0 style/Global.qml PropText 1.0 style/PiText.qml +PropTextField 1.0 style/PiTextField.qml PropLabel 1.0 style/PiLabel.qml PropSplitter 1.0 style/PiSplitter.qml PropButton 1.0 style/PiButton.qml diff --git a/scripts/developer/utilities/lib/prop/style/PiComboBox.qml b/scripts/developer/utilities/lib/prop/style/PiComboBox.qml index 92164fefc5..9430228eba 100644 --- a/scripts/developer/utilities/lib/prop/style/PiComboBox.qml +++ b/scripts/developer/utilities/lib/prop/style/PiComboBox.qml @@ -16,7 +16,9 @@ ComboBox { id: valueCombo height: global.slimHeight - + width: 120 + implicitHeight: global.slimHeight + // look flat: true @@ -51,8 +53,6 @@ ComboBox { } background: Rectangle { - implicitWidth: 120 - implicitHeight: 40 color: global.colorBack border.color: valueCombo.popup.visible ? global.colorBorderLighter : global.colorBorderLight border.width: global.valueBorderWidth diff --git a/scripts/developer/utilities/lib/prop/style/PiTextField.qml b/scripts/developer/utilities/lib/prop/style/PiTextField.qml new file mode 100644 index 0000000000..8dfb9d88ee --- /dev/null +++ b/scripts/developer/utilities/lib/prop/style/PiTextField.qml @@ -0,0 +1,31 @@ +// +// Prop/style/PiTextField.qml +// +// Created by Sam Gateau on 9/24/2019 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +TextField { + id: control + Global { id: global } + implicitHeight: global.slimHeight + implicitWidth: 200 + + placeholderText: qsTr("Enter description") + + color: global.fontColor + font.pixelSize: global.fontSize + font.family: global.fontFamily + font.weight: global.fontWeight + + background: Rectangle { + color: (control.text.length > 0) ? global.colorBackHighlight : global.colorBackShadow + border.color: (control.text.length > 0) ? global.colorBorderHighight : "transparent" + } +} From 2a78fc7b384f5c7b3d837bee0318df23819cf43d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 24 Sep 2019 14:29:09 -0700 Subject: [PATCH 12/21] Remove the auto refresh list of resource because it takes too much time, instead user has to press refresh button --- .../cache/cash/ResourceCacheInspector.qml | 58 +++++++++++-------- .../utilities/lib/prop/style/PiButton.qml | 3 + 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index 9b1ab907f9..fdf3137caf 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -58,10 +58,11 @@ Item { needFreshList = true } - Timer { + + /* Timer { interval: 2000; running: true; repeat: true onTriggered: pullFreshValues() - } + }*/ function pullFreshValues() { if (needFreshList) { @@ -138,34 +139,46 @@ Item { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - margin: global.horizontalMargin - + Item { anchors.left: parent.left anchors.right: parent.right height: totalCount.height - Prop.PropScalar { - id: totalCount + Prop.PropButton { + id: refreshButton anchors.left: parent.left - anchors.right: parent.horizontalCenter - label: "Count" - object: root.cache - property: "numTotal" - integral: true - readOnly: true - onSourceValueVarChanged: { updateItemListFromCache() } + anchors.verticalCenter: parent.verticalCenter + text: "Refresh" + color: needFreshList ? global.colorOrangeAccent : global.fontColor + onPressed: { pullFreshValues() } } - Prop.PropScalar { - id: cachedCount - anchors.left: parent.horizontalCenter + + Item { + anchors.left: refreshButton.right anchors.right: parent.right - label: "Cached" - object: root.cache - property: "numCached" - integral: true - readOnly: true - onSourceValueVarChanged: { updateItemListFromCache() } + Prop.PropScalar { + id: totalCount + anchors.left: parent.left + anchors.right: parent.horizontalCenter + label: "Count" + object: root.cache + property: "numTotal" + integral: true + readOnly: true + onSourceValueVarChanged: { updateItemListFromCache() } + } + Prop.PropScalar { + id: cachedCount + anchors.left: parent.horizontalCenter + anchors.right: parent.right + label: "Cached" + object: root.cache + property: "numCached" + integral: true + readOnly: true + onSourceValueVarChanged: { updateItemListFromCache() } + } } } Item { @@ -210,7 +223,6 @@ Item { opacity: (nameFilter.text.length > 0) ? 1.0 : 0.5 } } - Prop.Prop } Component { diff --git a/scripts/developer/utilities/lib/prop/style/PiButton.qml b/scripts/developer/utilities/lib/prop/style/PiButton.qml index 654d47e76d..5469431d81 100644 --- a/scripts/developer/utilities/lib/prop/style/PiButton.qml +++ b/scripts/developer/utilities/lib/prop/style/PiButton.qml @@ -16,10 +16,13 @@ Button { id: control text: "" spacing: 0 + property alias color: theContentItem.color contentItem: PiText { + id: theContentItem text: control.text horizontalAlignment: Text.AlignHCenter + color: global.fontColor } background: Rectangle { From 0d9cd69d94c7caef514e5832ab596e61e704cfcf Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 24 Sep 2019 18:10:57 -0700 Subject: [PATCH 13/21] SImplifying Page.js, and adding a REsourceInspector --- libraries/networking/src/ResourceCache.cpp | 6 +- scripts/developer/utilities/cache/cash.js | 33 +++++------ .../developer/utilities/cache/cash/Page.js | 21 ++++++- .../cache/cash/ResourceCacheInspector.qml | 12 ++-- .../cache/cash/ResourceInspector.qml | 58 +++++++++++++++++++ 5 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 scripts/developer/utilities/cache/cash/ResourceInspector.qml diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index f8d5ecf28e..25d40ed659 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -320,11 +320,11 @@ void ResourceCache::refreshAll() { QVariantList ResourceCache::getResourceList() { QVariantList list; - if (QThread::currentThread() != thread()) { + /*if (QThread::currentThread() != thread()) { // NOTE: invokeMethod does not allow a const QObject* BLOCKING_INVOKE_METHOD(this, "getResourceList", Q_RETURN_ARG(QVariantList, list)); - } else { + } else {*/ QList resources; { QReadLocker locker(&_resourcesLock); @@ -334,7 +334,7 @@ QVariantList ResourceCache::getResourceList() { for (auto& resource : resources) { list << resource; } - } + /* }*/ return list; } diff --git a/scripts/developer/utilities/cache/cash.js b/scripts/developer/utilities/cache/cash.js index b575b481c7..2181a50c36 100644 --- a/scripts/developer/utilities/cache/cash.js +++ b/scripts/developer/utilities/cache/cash.js @@ -5,25 +5,20 @@ function openView() { //window.closed.connect(function() { Script.stop(); }); - var pages = new Pages(); + var pages = new Pages(); function fromQml(message) { console.log(JSON.stringify(message)) + if (message.method == "inspectResource") { + pages.open("openResourceInspector") + pages.sendTo("openResourceInspector", message) + return; + } if (pages.open(message.method)) { return; } } - var cashWindow function openCashWindow(window) { - if (cashWindow !== undefined) { - activeWindow.fromQml.disconnect(fromQml); - } - if (window !== undefined) { - window.fromQml.connect(fromQml); - } - cashWindow = window; - - var onMousePressEvent = function (e) { }; Controller.mousePressEvent.connect(onMousePressEvent); @@ -38,23 +33,21 @@ function openView() { } function closeCashWindow() { - if (cashWindow !== undefined) { - activeWindow.fromQml.disconnect(fromQml); - } - cashWindow = {}; - Controller.mousePressEvent.disconnect(onMousePressEvent); Controller.mouseReleaseEvent.disconnect(onMouseReleaseEvent); Controller.mouseMoveEvent.disconnect(onMouseMoveEvent); pages.clear(); } + - pages.addPage('Cash', 'Cash', "../cash.qml", 300, 500, openCashWindow, closeCashWindow); - pages.addPage('openModelCacheInspector', 'Model Cache Inspector', "./ModelCacheInspector.qml", 300, 500); - pages.addPage('openMaterialCacheInspector', 'Material Cache Inspector', "./MaterialCacheInspector.qml", 300, 500); - pages.addPage('openTextureCacheInspector', 'Texture Cache Inspector', "./TextureCacheInspector.qml", 300, 500); + pages.addPage('Cash', 'Cash', "../cash.qml", 300, 500, fromQml, openCashWindow, closeCashWindow); + pages.addPage('openModelCacheInspector', 'Model Cache Inspector', "./ModelCacheInspector.qml", 300, 500, fromQml); + pages.addPage('openMaterialCacheInspector', 'Material Cache Inspector', "./MaterialCacheInspector.qml", 300, 500, fromQml); + pages.addPage('openTextureCacheInspector', 'Texture Cache Inspector', "./TextureCacheInspector.qml", 300, 500, fromQml); pages.addPage('openAnimationCacheInspector', 'Animation Cache Inspector', "./AnimationCacheInspector.qml", 300, 500); pages.addPage('openSoundCacheInspector', 'Sound Cache Inspector', "./SoundCacheInspector.qml", 300, 500); + pages.addPage('openResourceInspector', 'Resource Inspector', "./ResourceInspector.qml", 300, 500); + pages.open('Cash'); diff --git a/scripts/developer/utilities/cache/cash/Page.js b/scripts/developer/utilities/cache/cash/Page.js index 06c9704abf..d24af3d1ba 100644 --- a/scripts/developer/utilities/cache/cash/Page.js +++ b/scripts/developer/utilities/cache/cash/Page.js @@ -10,11 +10,12 @@ "use strict"; (function() { -function Page(title, qmlurl, width, height, onViewCreated, onViewClosed) { +function Page(title, qmlurl, width, height, onFromQml, onViewCreated, onViewClosed) { this.title = title; this.qml = qmlurl; this.width = width; this.height = height; + this.onFromQml = onFromQml; this.onViewCreated = onViewCreated; this.onViewClosed = onViewClosed; @@ -30,6 +31,9 @@ Page.prototype.killView = function () { //this.window.closed.disconnect(function () { // this.killView(); //}); + if (this.onFromQml) { + this.window.fromQml.disconnect(this.onFromQml) + } this.window.close(); this.window = false; } @@ -45,6 +49,9 @@ Page.prototype.createView = function () { size: {x: this.width, y: this.height} }); this.onViewCreated(this.window); + if (this.onFromQml) { + this.window.fromQml.connect(this.onFromQml) + } this.window.closed.connect(function () { that.killView(); that.onViewClosed(); @@ -57,7 +64,7 @@ Pages = function () { this._pages = {}; }; -Pages.prototype.addPage = function (command, title, qmlurl, width, height, onViewCreated, onViewClosed) { +Pages.prototype.addPage = function (command, title, qmlurl, width, height, onFromQml, onViewCreated, onViewClosed) { if (onViewCreated === undefined) { // Workaround for bad linter onViewCreated = function(window) {}; @@ -66,7 +73,7 @@ Pages.prototype.addPage = function (command, title, qmlurl, width, height, onVie // Workaround for bad linter onViewClosed = function() {}; } - this._pages[command] = new Page(title, qmlurl, width, height, onViewCreated, onViewClosed); + this._pages[command] = new Page(title, qmlurl, width, height, onFromQml, onViewCreated, onViewClosed); }; Pages.prototype.open = function (command) { @@ -87,4 +94,12 @@ Pages.prototype.clear = function () { this._pages = {}; }; +Pages.prototype.sendTo = function (command, message) { + if (!this._pages[command]) { + print("Pages: unknown command = " + command); + return; + } + this._pages[command].window.sendToQml(message); +}; + }()); diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index fdf3137caf..733472cb9e 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -30,6 +30,10 @@ Item { } } + function requestResourceDetails(resourceURL) { + sendToScript({method: "inspectResource", params: {url: resourceURL, semantic: cacheResourceName}}); + } + Component.onCompleted: { resetItemListFromCache(); } @@ -66,7 +70,7 @@ Item { function pullFreshValues() { if (needFreshList) { - console.log("Updating " + cacheResourceName + "cache list") + //console.log("Updating " + cacheResourceName + "cache list") updateItemList(fetchItemsList()) needFreshList = false } @@ -234,12 +238,12 @@ Item { height: item.height onPressed: {held = true} onReleased: {held = false} - + onDoubleClicked: { requestResourceDetails(model.url) } Rectangle { id: item width: parent.width height: global.slimHeight - color: dragArea.held ? global.colorBackHighlight : (model.identifier % 2 ? global.colorBackShadow : global.colorBack) + color: dragArea.held ? global.colorBackHighlight : (index % 2 ? global.colorBackShadow : global.colorBack) Row { id: itemRow anchors.verticalCenter : parent.verticalCenter @@ -324,7 +328,7 @@ Item { ] function refreshFilter() { - console.log("refreshFilter! token = " + textFilter + " field = " + filterField) + //console.log("refreshFilter! token = " + textFilter + " field = " + filterField) acceptItem = acceptItemArray[(textFilter.length != 0) * + (1 + filterField)] } diff --git a/scripts/developer/utilities/cache/cash/ResourceInspector.qml b/scripts/developer/utilities/cache/cash/ResourceInspector.qml new file mode 100644 index 0000000000..099eb735d0 --- /dev/null +++ b/scripts/developer/utilities/cache/cash/ResourceInspector.qml @@ -0,0 +1,58 @@ +// +// ResourceInspector.qml +// +// Created by Sam Gateau on 2019-09-24 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// +import QtQuick 2.12 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 +import QtQml.Models 2.12 + +import "../../lib/prop" as Prop + +Item { + id: root; + Prop.Global { id: global } + + anchors.fill: parent.fill + property var cache: {} + property string cacheResourceName: "" + + function fromScript(message) { + switch (message.method) { + case "inspectResource": + inspectResource(message.params.url, message.params.semantic) + break; + } + } + + function inspectResource(url, semantic) { + console.log("inspectResource :" + url + " as " + semantic) + info.text = "url: " + url + "\nsemantic: " + semantic + "\n"; + + if (semantic == "Texture") { + var res = TextureCache.prefetch(url, 0) + info.text += JSON.stringify(res); + } else if (semantic == "Model") { + var res = ModelCache.prefetch(url) + info.text += JSON.stringify(res); + } + } + + TextEdit { + id: info + anchors.fill: parent + text: "Click an object to get material JSON" + width: root.width + font.pointSize: 10 + color: "#FFFFFF" + readOnly: true + selectByMouse: true + wrapMode: Text.WordWrap + } +} + From dc40c530a305c5553c5e93c13872fcaa33308164 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 25 Sep 2019 17:53:59 -0700 Subject: [PATCH 14/21] INstrumenting the code more... --- .../src/RenderableMaterialEntityItem.cpp | 8 +- libraries/graphics/src/graphics/Material.cpp | 11 +- libraries/graphics/src/graphics/Material.h | 3 +- .../src/material-networking/MaterialCache.cpp | 5 +- .../src/material-networking/MaterialCache.h | 2 +- .../src/model-networking/ModelCache.cpp | 10 +- scripts/developer/utilities/cache/cash.qml | 15 --- .../cache/cash/ResourceCacheInspector.qml | 70 ++++++---- .../utilities/cache/cash/SortFilterModel.qml | 125 +++++++----------- .../developer/utilities/lib/prop/PropItem.qml | 6 +- 10 files changed, 128 insertions(+), 127 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index eae0561343..c8dc701989 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -11,6 +11,9 @@ #include "RenderPipelines.h" #include "GeometryCache.h" +#include "EntitiesRendererLogging.h" + + using namespace render; using namespace render::entities; @@ -195,7 +198,10 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo auto material = getMaterial(); bool newTexturesLoaded = material ? !material->isMissingTexture() : false; if (!_texturesLoaded && newTexturesLoaded) { - material->checkResetOpacityMap(); + bool changed = material->checkResetOpacityMap(); + if (changed) { + qCWarning(entitiesrenderer) << "opacity change detected for material " << material->getName().c_str(); + } } _texturesLoaded = newTexturesLoaded; } diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index 7524414947..aeb37fc8d2 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -14,6 +14,8 @@ #include +#include "GraphicsLogging.h" + using namespace graphics; using namespace gpu; @@ -162,7 +164,8 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur } -void Material::resetOpacityMap() const { +bool Material::resetOpacityMap() const { + auto previous = _key.getAlphaMapMode(); // Clear the previous flags _key.setOpacityMaskMap(false); _key.setTranslucentMap(false); @@ -186,6 +189,12 @@ void Material::resetOpacityMap() const { } } } + auto newious = _key.getAlphaMapMode(); + if (previous != newious) { + qCWarning(graphicsLog) << "opacity change detected for material " << _name.c_str(); + return true; + } + return false; } const TextureMapPointer Material::getTextureMap(MapChannel channel) const { diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index adfe53a962..dd97aa1216 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -358,7 +358,8 @@ public: // Albedo maps cannot have opacity detected until they are loaded // This method allows const changing of the key/schemaBuffer without touching the map - void resetOpacityMap() const; + // return true if the opacity changed, flase otherwise + bool resetOpacityMap() const; // conversion from legacy material properties to PBR equivalent static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; } diff --git a/libraries/material-networking/src/material-networking/MaterialCache.cpp b/libraries/material-networking/src/material-networking/MaterialCache.cpp index 087e1ca049..41ea04135b 100644 --- a/libraries/material-networking/src/material-networking/MaterialCache.cpp +++ b/libraries/material-networking/src/material-networking/MaterialCache.cpp @@ -748,13 +748,14 @@ bool NetworkMaterial::isMissingTexture() { return false; } -void NetworkMaterial::checkResetOpacityMap() { +bool NetworkMaterial::checkResetOpacityMap() { // If material textures are loaded, check the material translucency // FIXME: This should not be done here. The opacity map should already be reset in Material::setTextureMap. // However, currently that code can be called before the albedo map is defined, so resetOpacityMap will fail. // Geometry::areTexturesLoaded() is called repeatedly until it returns true, so we do the check here for now const auto& albedoTexture = _textures[NetworkMaterial::MapChannel::ALBEDO_MAP]; if (albedoTexture.texture) { - resetOpacityMap(); + return resetOpacityMap(); } + return false; } diff --git a/libraries/material-networking/src/material-networking/MaterialCache.h b/libraries/material-networking/src/material-networking/MaterialCache.h index 18aa5e5994..aa103adb1e 100644 --- a/libraries/material-networking/src/material-networking/MaterialCache.h +++ b/libraries/material-networking/src/material-networking/MaterialCache.h @@ -34,7 +34,7 @@ public: void setLightMap(const QUrl& url); bool isMissingTexture(); - void checkResetOpacityMap(); + bool checkResetOpacityMap(); class Texture { public: diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 1ed1c65358..1fcfcfcc70 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -472,7 +472,10 @@ bool Geometry::areTexturesLoaded() const { return false; } - material->checkResetOpacityMap(); + bool changed = material->checkResetOpacityMap(); + if (changed) { + qCWarning(modelnetworking) << "Material list: opacity change detected for material " << material->getName().c_str(); + } } for (auto& materialMapping : _materialMapping) { @@ -483,7 +486,10 @@ bool Geometry::areTexturesLoaded() const { return false; } - materialPair.second->checkResetOpacityMap(); + bool changed = materialPair.second->checkResetOpacityMap(); + if (changed) { + qCWarning(modelnetworking) << "Mapping list: opacity change detected for material " << materialPair.first.c_str(); + } } } } diff --git a/scripts/developer/utilities/cache/cash.qml b/scripts/developer/utilities/cache/cash.qml index e143a82e62..159ce95c5f 100644 --- a/scripts/developer/utilities/cache/cash.qml +++ b/scripts/developer/utilities/cache/cash.qml @@ -109,21 +109,6 @@ Rectangle { } width:column.width } - - Prop.PropScalar { - label: "Texture Loading" - object: TextureCache - property: "numLoading" - integral: true - readOnly: true - } - Prop.PropScalar { - label: "Model Loading" - object: ModelCache - property: "numLoading" - integral: true - readOnly: true - } } } } diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index 733472cb9e..7d14a07e13 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -63,14 +63,13 @@ Item { } - /* Timer { + Timer { interval: 2000; running: true; repeat: true onTriggered: pullFreshValues() - }*/ + } function pullFreshValues() { if (needFreshList) { - //console.log("Updating " + cacheResourceName + "cache list") updateItemList(fetchItemsList()) needFreshList = false } @@ -127,7 +126,9 @@ Item { var item = itemList[i] currentItemsList.push(item) resourceItemsModel.append(packItemEntry(item, currentItemsList.length -1)) - } + } + // At the end of it, force an update + visualModel.forceUpdate() } function updateItemList(newItemList) { @@ -148,6 +149,7 @@ Item { anchors.left: parent.left anchors.right: parent.right height: totalCount.height + id: headerTop Prop.PropButton { id: refreshButton @@ -158,30 +160,46 @@ Item { onPressed: { pullFreshValues() } } - Item { + GridLayout { anchors.left: refreshButton.right anchors.right: parent.right - Prop.PropScalar { - id: totalCount - anchors.left: parent.left - anchors.right: parent.horizontalCenter - label: "Count" - object: root.cache - property: "numTotal" - integral: true - readOnly: true - onSourceValueVarChanged: { updateItemListFromCache() } + id: headerCountLane + columns: 3 + + Item { + Layout.fillWidth: true + Prop.PropScalar { + id: itemCount + label: "Count" + object: root.cache + property: "numTotal" + integral: true + readOnly: true + } } - Prop.PropScalar { - id: cachedCount - anchors.left: parent.horizontalCenter - anchors.right: parent.right - label: "Cached" - object: root.cache - property: "numCached" - integral: true - readOnly: true - onSourceValueVarChanged: { updateItemListFromCache() } + Item { + Layout.fillWidth: true + Prop.PropScalar { + id: totalCount + label: "Count" + object: root.cache + property: "numTotal" + integral: true + readOnly: true + onSourceValueVarChanged: { updateItemListFromCache() } + } + } + Item { + Layout.fillWidth: true + Prop.PropScalar { + id: cachedCount + label: "Cached" + object: root.cache + property: "numCached" + integral: true + readOnly: true + onSourceValueVarChanged: { updateItemListFromCache() } + } } } } @@ -331,7 +349,7 @@ Item { //console.log("refreshFilter! token = " + textFilter + " field = " + filterField) acceptItem = acceptItemArray[(textFilter.length != 0) * + (1 + filterField)] } - + delegate: resouceItemDelegate } diff --git a/scripts/developer/utilities/cache/cash/SortFilterModel.qml b/scripts/developer/utilities/cache/cash/SortFilterModel.qml index a4a9c3f6a3..08ad8d1dbd 100644 --- a/scripts/developer/utilities/cache/cash/SortFilterModel.qml +++ b/scripts/developer/utilities/cache/cash/SortFilterModel.qml @@ -6,96 +6,71 @@ DelegateModel { property var lessThan: function(left, right) { return true; } property var acceptItem: function(item) { return true; } -/* - function insertPosition(lessThan, item) { - var lower = 0 - var upper = items.count - while (lower < upper) { - var middle = Math.floor(lower + (upper - lower) / 2) - var result = lessThan(item.model, items.get(middle).model); - if (result) { - upper = middle - } else { - lower = middle + 1 - } - } - return lower - } - function sort(lessThan) { - while (unsortedItems.count > 0) { - var item = unsortedItems.get(0) - - var index = insertPosition(lessThan, item) - - item.groups = "items" - items.move(item.itemsIndex, index) + function insertPosition(lessThanFunctor, item) { + var lower = 0 + var upper = visibleItems.count + while (lower < upper) { + var middle = Math.floor(lower + (upper - lower) / 2) + var result = lessThanFunctor(item.model, visibleItems.get(middle).model); + if (result) { + upper = middle + } else { + lower = middle + 1 } } -*/ - function insertPosition(lessThanFunctor, item) { - var lower = 0 - var upper = visibleItems.count - while (lower < upper) { - var middle = Math.floor(lower + (upper - lower) / 2) - var result = lessThanFunctor(item.model, visibleItems.get(middle).model); - if (result) { - upper = middle - } else { - lower = middle + 1 - } - } - return lower - } + return lower + } - function sort(lessThanFunctor, acceptItemFunctor) { - while (unsortedItems.count > 0) { - var item = unsortedItems.get(0) - - if (acceptItemFunctor(item.model)) { - var index = insertPosition(lessThanFunctor, item) + function sortAndFilter(lessThanFunctor, acceptItemFunctor) { + while (unsortedItems.count > 0) { + var item = unsortedItems.get(0) + + if (acceptItemFunctor(item.model)) { + var index = insertPosition(lessThanFunctor, item) - item.groups = ["items","visible"] - visibleItems.move(item.visibleIndex, index) - } else { - item.groups = ["items"] - } + item.groups = ["items","visible"] + visibleItems.move(item.visibleIndex, index) + } else { + item.groups = ["items"] } } + } + // Private bool to track when items changed and view is dirty + property bool itemsDirty: true function update() { + console.log("SortFilterMode: update and sort and filter items !!" + items.count); if (items.count > 0) { items.setGroups(0, items.count, ["items","unsorted"]); } - sort(lessThan, acceptItem) - /* - // Step 1: Filter items - var visible = []; - for (var i = 0; i < items.count; ++i) { - var item = items.get(i); - if (filterAcceptsItem(item.model)) { - visible.push(item); - } - } - - // Step 2: Sort the list of visible items - visible.sort(function(a, b) { - return lessThan(a.model, b.model) ? -1 : 1; - }); - - // Step 3: Add all items to the visible group: - for (i = 0; i < visible.length; ++i) { - item = visible[i]; - item.inVisible = true; - if (item.visibleIndex !== i) { - visibleItems.move(item.visibleIndex, i, 1); - } - } - */ + sortAndFilter(lessThan, acceptItem) + itemsDirty = false; + itemsUpdated() } - items.onChanged: update() + signal itemsUpdated() + + function updateOnItemsChanged() { + itemsDirty = true; + if (isAutoUpdateOnChanged) { + update() + } + } + + property bool isAutoUpdateOnChanged: false + function setAutoUpdateOnChanged(enabled) { + isAutoUpdateOnChanged = enabled + if (enabled) { + update() + } + } + + function forceUpdate() { + update(); + } + items.onChanged: updateOnItemsChanged() onLessThanChanged: update() onAcceptItemChanged: update() diff --git a/scripts/developer/utilities/lib/prop/PropItem.qml b/scripts/developer/utilities/lib/prop/PropItem.qml index fe2364b59a..24e2ecaa9a 100644 --- a/scripts/developer/utilities/lib/prop/PropItem.qml +++ b/scripts/developer/utilities/lib/prop/PropItem.qml @@ -33,11 +33,11 @@ Item { // PropItem is stretching horizontally accross its parent // Fixed height + height: global.lineHeight anchors.left: parent.left anchors.right: parent.right - height: global.lineHeight - anchors.leftMargin: global.horizontalMargin - anchors.rightMargin: global.horizontalMargin + // anchors.leftMargin: global.horizontalMargin + // anchors.rightMargin: global.horizontalMargin // LabelControl And SplitterControl are on the left side of the PropItem property bool showLabel: true From 9d999baab2cb030724aca66fa8464f95d101c6b9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Sep 2019 11:59:01 -0700 Subject: [PATCH 15/21] FIrst pass to clean up before pushing a pr: --- interface/src/graphics/GraphicsEngine.cpp | 22 +------------------ .../src/RenderableMaterialEntityItem.cpp | 8 +------ .../src/RenderableModelEntityItem.cpp | 6 ++--- libraries/gl/src/gl/GLHelpers.cpp | 1 - .../GraphicsScriptingInterface.cpp | 6 ++--- libraries/graphics/src/graphics/Material.cpp | 4 ++-- libraries/graphics/src/graphics/Material.h | 10 +++++++++ libraries/graphics/src/graphics/Material.slh | 19 ++++++++-------- libraries/networking/src/ResourceCache.cpp | 15 ++++--------- libraries/networking/src/ResourceCache.h | 14 ++++-------- .../render-utils/src/RenderPipelines.cpp | 8 ++++++- libraries/render/src/render/EngineStats.cpp | 3 ++- libraries/render/src/render/EngineStats.h | 5 ----- tools/gpu-frame-player/src/RenderThread.cpp | 1 + 14 files changed, 46 insertions(+), 76 deletions(-) diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp index 98ad7c0ad7..ab7195a01b 100644 --- a/interface/src/graphics/GraphicsEngine.cpp +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -240,7 +240,6 @@ void GraphicsEngine::render_performFrame() { renderArgs._context->setStereoViews(stereoEyeOffsets); } } - bool renderScene = true; gpu::FramebufferPointer finalFramebuffer; QSize finalFramebufferSize; { @@ -277,32 +276,13 @@ void GraphicsEngine::render_performFrame() { qApp->getApplicationCompositor().setFrameInfo(_renderFrameCount, eyeToWorld, sensorToWorld); } - - if (renderScene) { + { PROFILE_RANGE(render, "/runRenderFrame"); renderArgs._hudOperator = displayPlugin->getHUDOperator(); renderArgs._hudTexture = qApp->getApplicationOverlay().getOverlayTexture(); renderArgs._takingSnapshot = qApp->takeSnapshotOperators(snapshotOperators); renderArgs._blitFramebuffer = finalFramebuffer; render_runRenderFrame(&renderArgs); - } else { - // Instead of clearing, drawing the splash screen background (that looks like the default skybox) - gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) { - batch.setFramebuffer(finalFramebuffer); - batch.enableSkybox(true); - batch.enableStereo(isStereo); - batch.clearDepthStencilFramebuffer(1.0, 0); - batch.setViewportTransform({ 0, 0, finalFramebuffer->getSize() }); - _splashScreen->render(batch, viewFrustum, renderArgs._renderMethod == RenderArgs::RenderMethod::FORWARD); - }); - - // THen just use the HUD operator of thedisplay plugin - gpu::doInBatch("drawHUD", renderArgs._context, [&](gpu::Batch& batch) { - batch.setFramebuffer(finalFramebuffer); - // TODO we should do more transform setup here just like in "REnderHUDLayerTask.cpp CompositeHUD job if we wanted to support stereo - displayPlugin->getHUDOperator()(batch, qApp->getApplicationOverlay().getOverlayTexture()); - }); - // And voila } } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index c8dc701989..eae0561343 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -11,9 +11,6 @@ #include "RenderPipelines.h" #include "GeometryCache.h" -#include "EntitiesRendererLogging.h" - - using namespace render; using namespace render::entities; @@ -198,10 +195,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo auto material = getMaterial(); bool newTexturesLoaded = material ? !material->isMissingTexture() : false; if (!_texturesLoaded && newTexturesLoaded) { - bool changed = material->checkResetOpacityMap(); - if (changed) { - qCWarning(entitiesrenderer) << "opacity change detected for material " << material->getName().c_str(); - } + material->checkResetOpacityMap(); } _texturesLoaded = newTexturesLoaded; } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index a91d07947a..6314cc8ce4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -41,7 +41,6 @@ void ModelEntityWrapper::setModel(const ModelPointer& model) { if (_model) { _needsInitialSimulation = true; } - } }); } @@ -1432,13 +1431,12 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } } - bool currentTexturesLoaded = resultWithReadLock([&] { return _texturesLoaded; }); - if (!currentTexturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) { + if (!_texturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) { withWriteLock([&] { _texturesLoaded = true; }); model->updateRenderItems(); - } else if (!currentTexturesLoaded) { + } else if (!_texturesLoaded) { emit requestRenderUpdate(); } diff --git a/libraries/gl/src/gl/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp index ddb93e0fa0..b2c98e91d3 100644 --- a/libraries/gl/src/gl/GLHelpers.cpp +++ b/libraries/gl/src/gl/GLHelpers.cpp @@ -287,7 +287,6 @@ const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() { // Qt Quick may need a depth and stencil buffer. Always make sure these are available. format.setDepthBufferSize(DEFAULT_GL_DEPTH_BUFFER_BITS); format.setStencilBufferSize(DEFAULT_GL_STENCIL_BUFFER_BITS); - format.setColorSpace(QSurfaceFormat::ColorSpace::sRGBColorSpace); auto glversion = ::gl::getTargetVersion(); format.setMajorVersion(GL_GET_MAJOR_VERSION(glversion)); format.setMinorVersion(GL_GET_MINOR_VERSION(glversion)); diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp index 02083af932..5abe568909 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp @@ -382,8 +382,7 @@ namespace scriptable { if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_VAL_BIT)) { obj.setProperty("scattering", FALLTHROUGH); - } - else if (material.key.isScattering()) { + } else if (material.key.isScattering()) { obj.setProperty("scattering", material.scattering); } @@ -427,12 +426,11 @@ namespace scriptable { obj.setProperty("keys.isTexelOpaque", material.key.isTexelOpaque()); obj.setProperty("keys.isSurfaceOpaque", material.key.isSurfaceOpaque()); - if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_MASK_MAP_BIT)) { + if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT)) { obj.setProperty("opacityMapMode", FALLTHROUGH); obj.setProperty("alphaCutoff", FALLTHROUGH); } else if (material.key.isGlossy()) { obj.setProperty("opacityMapMode", material.opacityMode); - obj.setProperty("alphaCutoff", material.alphaCutoff); } diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index aeb37fc8d2..21ba2872a4 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -122,7 +122,7 @@ void Material::setScattering(float scattering) { void Material::setAlphaCutoff(float alphaCutoff) { alphaCutoff = glm::clamp(alphaCutoff, 0.0f, 1.0f); - // _key.setAlphaCutoff(alphaCutoff != DEFAULT_ALPHA_CUTOFF); + _key.setAlphaCutoff(alphaCutoff != DEFAULT_ALPHA_CUTOFF); _alphaCutoff = alphaCutoff; } @@ -191,7 +191,7 @@ bool Material::resetOpacityMap() const { } auto newious = _key.getAlphaMapMode(); if (previous != newious) { - qCWarning(graphicsLog) << "opacity change detected for material " << _name.c_str(); + //opacity change detected for this material return true; } return false; diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index dd97aa1216..94d9a9b3f0 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -43,6 +43,7 @@ public: OPACITY_VAL_BIT, OPACITY_MASK_MAP_BIT, // Opacity Map and Opacity MASK map are mutually exclusive OPACITY_TRANSLUCENT_MAP_BIT, + ALPHA_CUTOFF_VAL_BIT, SCATTERING_VAL_BIT, // THe map bits must be in the same sequence as the enum names for the map channels @@ -101,6 +102,8 @@ public: Builder& withTranslucentFactor() { _flags.set(OPACITY_VAL_BIT); return (*this); } + Builder& withAlphaCutoff() { _flags.set(ALPHA_CUTOFF_VAL_BIT); return (*this); } + Builder& withScattering() { _flags.set(SCATTERING_VAL_BIT); return (*this); } Builder& withEmissiveMap() { _flags.set(EMISSIVE_MAP_BIT); return (*this); } @@ -168,6 +171,9 @@ public: void setTranslucentFactor(bool value) { _flags.set(OPACITY_VAL_BIT, value); } bool isTranslucentFactor() const { return _flags[OPACITY_VAL_BIT]; } + void setAlphaCutoff(bool value) { _flags.set(ALPHA_CUTOFF_VAL_BIT, value); } + bool isAlphaCutoff() const { return _flags[ALPHA_CUTOFF_VAL_BIT]; } + void setTranslucentMap(bool value) { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT, value); } bool isTranslucentMap() const { return _flags[OPACITY_TRANSLUCENT_MAP_BIT]; } @@ -264,6 +270,9 @@ public: Builder& withoutTranslucentFactor() { _value.reset(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); } Builder& withTranslucentFactor() { _value.set(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); } + Builder& withoutAlphaCutoff() { _value.reset(MaterialKey::ALPHA_CUTOFF_VAL_BIT); _mask.set(MaterialKey::ALPHA_CUTOFF_VAL_BIT); return (*this); } + Builder& withAlphaCutoff() { _value.set(MaterialKey::ALPHA_CUTOFF_VAL_BIT); _mask.set(MaterialKey::ALPHA_CUTOFF_VAL_BIT); return (*this); } + Builder& withoutTranslucentMap() { _value.reset(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } Builder& withTranslucentMap() { _value.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } @@ -324,6 +333,7 @@ public: void setOpacity(float opacity); float getOpacity() const { return _opacity; } + static const MaterialKey::AlphaMapMode DEFAULT_ALPHA_MAP_MODE; void setAlphaMapMode(MaterialKey::AlphaMapMode alphaMode); MaterialKey::AlphaMapMode getAlphaMapMode() const; diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index 8ebf66417c..76847c081f 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -85,16 +85,17 @@ const BITFIELD GLOSSY_VAL_BIT = 0x00000010; const BITFIELD OPACITY_VAL_BIT = 0x00000020; const BITFIELD OPACITY_MASK_MAP_BIT = 0x00000040; const BITFIELD OPACITY_TRANSLUCENT_MAP_BIT = 0x00000080; -const BITFIELD SCATTERING_VAL_BIT = 0x00000100; +const BITFIELD ALPHA_CUTOFF_VAL_BIT = 0x00000100; +const BITFIELD SCATTERING_VAL_BIT = 0x00000200; -const BITFIELD EMISSIVE_MAP_BIT = 0x00000200; -const BITFIELD ALBEDO_MAP_BIT = 0x00000400; -const BITFIELD METALLIC_MAP_BIT = 0x00000800; -const BITFIELD ROUGHNESS_MAP_BIT = 0x00001000; -const BITFIELD NORMAL_MAP_BIT = 0x00002000; -const BITFIELD OCCLUSION_MAP_BIT = 0x00004000; -const BITFIELD LIGHTMAP_MAP_BIT = 0x00008000; -const BITFIELD SCATTERING_MAP_BIT = 0x00010000; +const BITFIELD EMISSIVE_MAP_BIT = 0x00000400; +const BITFIELD ALBEDO_MAP_BIT = 0x00000800; +const BITFIELD METALLIC_MAP_BIT = 0x00001000; +const BITFIELD ROUGHNESS_MAP_BIT = 0x00002000; +const BITFIELD NORMAL_MAP_BIT = 0x00004000; +const BITFIELD OCCLUSION_MAP_BIT = 0x00008000; +const BITFIELD LIGHTMAP_MAP_BIT = 0x00010000; +const BITFIELD SCATTERING_MAP_BIT = 0x00020000; <@endif@> diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 25d40ed659..88a4f5bf32 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -320,11 +320,11 @@ void ResourceCache::refreshAll() { QVariantList ResourceCache::getResourceList() { QVariantList list; - /*if (QThread::currentThread() != thread()) { + if (QThread::currentThread() != thread()) { // NOTE: invokeMethod does not allow a const QObject* BLOCKING_INVOKE_METHOD(this, "getResourceList", Q_RETURN_ARG(QVariantList, list)); - } else {*/ + } else { QList resources; { QReadLocker locker(&_resourcesLock); @@ -334,7 +334,7 @@ QVariantList ResourceCache::getResourceList() { for (auto& resource : resources) { list << resource; } - /* }*/ + } return list; } @@ -517,13 +517,6 @@ void ResourceCache::updateTotalSize(const qint64& deltaSize) { emit dirty(); } -void ResourceCache::incrementNumLoading() { - _numLoadingResources++; -} -void ResourceCache::decrementNumLoading() { - _numLoadingResources--; -} - QList> ResourceCache::getLoadingRequests() { return DependencyManager::get()->getLoadingRequests(); } @@ -541,7 +534,7 @@ bool ResourceCache::attemptRequest(QSharedPointer resource) { auto sharedItems = DependencyManager::get(); if (sharedItems->appendRequest(resource)) { - resource->makeRequest(); + resource->makeRequest(); return true; } return false; diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index b9b339644e..259e14c650 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -200,21 +200,15 @@ class ResourceCache : public QObject { Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty) Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) - Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) - public: size_t getNumTotalResources() const { return _numTotalResources; } size_t getSizeTotalResources() const { return _totalResourcesSize; } size_t getNumCachedResources() const { return _numUnusedResources; } size_t getSizeCachedResources() const { return _unusedResourcesSize; } - size_t getNumLoadingResources() const { return _numLoadingResources; } Q_INVOKABLE QVariantList getResourceList(); - Q_INVOKABLE void incrementNumLoading(); - Q_INVOKABLE void decrementNumLoading(); - static void setRequestLimit(uint32_t limit); static uint32_t getRequestLimit() { return DependencyManager::get()->getRequestLimit(); } @@ -295,7 +289,6 @@ private: std::atomic _numTotalResources { 0 }; std::atomic _totalResourcesSize { 0 }; - std::atomic _numLoadingResources{ 0 }; // Cached resources QMap> _unusedResources; @@ -324,8 +317,10 @@ class ScriptableResourceCache : public QObject { Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty) Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) - Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) - + /**jsdoc + * @property {number} numGlobalQueriesPending - Total number of global queries pending (across all resource managers). Read-only. + * @property {number} numGlobalQueriesLoading - Total number of global queries pending (across all resource managers). Read-only. + */ Q_PROPERTY(size_t numGlobalQueriesPending READ getNumGlobalQueriesPending NOTIFY dirty) Q_PROPERTY(size_t numGlobalQueriesLoading READ getNumGlobalQueriesLoading NOTIFY dirty) @@ -402,7 +397,6 @@ private: size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); } size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); } size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); } - size_t getNumLoadingResources() const { return _resourceCache->getNumLoadingResources(); } size_t getNumGlobalQueriesPending() const { return ResourceCache::getLoadingRequestCount(); } size_t getNumGlobalQueriesLoading() const { return ResourceCache::getPendingRequestCount(); } diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 14ceb4f9be..42ff74476f 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -461,6 +461,13 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial wasSet = true; } break; + case graphics::MaterialKey::ALPHA_CUTOFF_VAL_BIT: + if (materialKey.isAlphaCutoff()) { + schema._alphaCutoff = material->getAlphaCutoff(); + schemaKey.setAlphaCutoff(true); + wasSet = true; + } + break; case graphics::MaterialKey::SCATTERING_VAL_BIT: if (materialKey.isScattering()) { schema._scattering = material->getScattering(); @@ -486,7 +493,6 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial schemaKey.setAlbedoMap(true); schemaKey.setOpacityMaskMap(material->getKey().isOpacityMaskMap()); schemaKey.setTranslucentMap(material->getKey().isTranslucentMap()); - schema._alphaCutoff = material->getAlphaCutoff(); } break; case graphics::MaterialKey::METALLIC_MAP_BIT: diff --git a/libraries/render/src/render/EngineStats.cpp b/libraries/render/src/render/EngineStats.cpp index 9f45f7e559..6fbd3e6f9c 100644 --- a/libraries/render/src/render/EngineStats.cpp +++ b/libraries/render/src/render/EngineStats.cpp @@ -63,5 +63,6 @@ void EngineStats::run(const RenderContextPointer& renderContext) { config->frameSetPipelineCount = _gpuStats._PSNumSetPipelines; config->frameSetInputFormatCount = _gpuStats._ISNumFormatChanges; - config->emitDirty(); + + // These new stat values are notified with the "newStats" signal triggered by the timer } diff --git a/libraries/render/src/render/EngineStats.h b/libraries/render/src/render/EngineStats.h index 9150e78f82..9f8be748f7 100644 --- a/libraries/render/src/render/EngineStats.h +++ b/libraries/render/src/render/EngineStats.h @@ -101,11 +101,6 @@ namespace render { quint32 frameSetPipelineCount{ 0 }; quint32 frameSetInputFormatCount{ 0 }; - - - - void emitDirty() { emit newStats(); } - }; class EngineStats { diff --git a/tools/gpu-frame-player/src/RenderThread.cpp b/tools/gpu-frame-player/src/RenderThread.cpp index ef553e59fc..6c0d3c7bba 100644 --- a/tools/gpu-frame-player/src/RenderThread.cpp +++ b/tools/gpu-frame-player/src/RenderThread.cpp @@ -188,6 +188,7 @@ void RenderThread::renderFrame(gpu::FramePointer& frame) { glDisable(GL_FRAMEBUFFER_SRGB); _gpuContext->executeBatch(*batch); + // Keep this raw gl code here for reference //glDisable(GL_FRAMEBUFFER_SRGB); //glClear(GL_COLOR_BUFFER_BIT); /* glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); From 24cc302a8bbf3365e17a38193535538c3990a29e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Sep 2019 16:56:00 -0700 Subject: [PATCH 16/21] second pass of cleaning on the code to make it ready for merge --- interface/src/graphics/GraphicsEngine.cpp | 1 + .../src/graphics-scripting/Forward.h | 7 +- .../GraphicsScriptingInterface.cpp | 20 ++-- libraries/graphics/src/graphics/Material.cpp | 4 +- libraries/graphics/src/graphics/Material.h | 92 +++++++++---------- libraries/graphics/src/graphics/Material.slh | 12 +-- .../src/graphics/MaterialTextures.slh | 19 ++-- .../src/material-networking/MaterialCache.cpp | 16 ++++ libraries/render-utils/src/model.slf | 48 +++++----- scripts/developer/utilities/cache/cash.js | 18 ++-- .../{cache/cash => lib/skit}/Page.js | 10 +- scripts/developer/utilities/render/luci.js | 24 ++--- .../developer/utilities/render/luci/Page.js | 90 ------------------ 13 files changed, 140 insertions(+), 221 deletions(-) rename scripts/developer/utilities/{cache/cash => lib/skit}/Page.js (89%) delete mode 100644 scripts/developer/utilities/render/luci/Page.js diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp index ab7195a01b..53c8bd7c18 100644 --- a/interface/src/graphics/GraphicsEngine.cpp +++ b/interface/src/graphics/GraphicsEngine.cpp @@ -240,6 +240,7 @@ void GraphicsEngine::render_performFrame() { renderArgs._context->setStereoViews(stereoEyeOffsets); } } + gpu::FramebufferPointer finalFramebuffer; QSize finalFramebufferSize; { diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h index c74c1c09bf..1295fc5722 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h +++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h @@ -50,6 +50,8 @@ namespace scriptable { * @property {string} emissiveMap * @property {string} albedoMap * @property {string} opacityMap + * @property {string} opacityMapMode + * @property {number|string} opacityCutoff * @property {string} metallicMap * @property {string} specularMap * @property {string} roughnessMap @@ -63,7 +65,6 @@ namespace scriptable { * @property {Mat4|string} texCoordTransform1 * @property {string} lightmapParams * @property {string} materialParams - * @property {string} opacityMode * @property {boolean} defaultFallthrough */ class ScriptableMaterial { @@ -79,13 +80,14 @@ namespace scriptable { float roughness; float metallic; float scattering; - float alphaCutoff; bool unlit; glm::vec3 emissive; glm::vec3 albedo; QString emissiveMap; QString albedoMap; QString opacityMap; + QString opacityMapMode; + float opacityCutoff; QString metallicMap; QString specularMap; QString roughnessMap; @@ -96,7 +98,6 @@ namespace scriptable { QString lightMap; QString scatteringMap; std::array texCoordTransforms; - QString opacityMode; bool defaultFallthrough; std::unordered_map propertyFallthroughs; // not actually exposed to script diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp index 5abe568909..ef3172119c 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp @@ -420,18 +420,16 @@ namespace scriptable { obj.setProperty("opacityMap", material.opacityMap); } - - obj.setProperty("keys.isOpaque", material.key.isOpaque()); - obj.setProperty("keys.isOpacityMaskMap", material.key.isOpacityMaskMap()); - obj.setProperty("keys.isTexelOpaque", material.key.isTexelOpaque()); - obj.setProperty("keys.isSurfaceOpaque", material.key.isSurfaceOpaque()); - - if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT)) { + if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT | graphics::MaterialKey::OPACITY_MASK_MAP_BIT)) { obj.setProperty("opacityMapMode", FALLTHROUGH); - obj.setProperty("alphaCutoff", FALLTHROUGH); - } else if (material.key.isGlossy()) { - obj.setProperty("opacityMapMode", material.opacityMode); - obj.setProperty("alphaCutoff", material.alphaCutoff); + } else if (material.key.getOpacityMapMode() != graphics::Material::DEFAULT_OPACITY_MAP_MODE) { + obj.setProperty("opacityMapMode", material.opacityMapMode); + } + + if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_CUTOFF_VAL_BIT)) { + obj.setProperty("opacityCutoff", FALLTHROUGH); + } else if (!material.key.isOpacityCutoff()) { + obj.setProperty("opacityCutoff", material.opacityCutoff); } if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OCCLUSION_MAP_BIT)) { diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index 21ba2872a4..48ff31e739 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -165,7 +165,7 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur } bool Material::resetOpacityMap() const { - auto previous = _key.getAlphaMapMode(); + auto previous = _key.getOpacityMapMode(); // Clear the previous flags _key.setOpacityMaskMap(false); _key.setTranslucentMap(false); @@ -189,7 +189,7 @@ bool Material::resetOpacityMap() const { } } } - auto newious = _key.getAlphaMapMode(); + auto newious = _key.getOpacityMapMode(); if (previous != newious) { //opacity change detected for this material return true; diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 94d9a9b3f0..d2bb7b77e3 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -43,7 +43,7 @@ public: OPACITY_VAL_BIT, OPACITY_MASK_MAP_BIT, // Opacity Map and Opacity MASK map are mutually exclusive OPACITY_TRANSLUCENT_MAP_BIT, - ALPHA_CUTOFF_VAL_BIT, + OPACITY_CUTOFF_VAL_BIT, SCATTERING_VAL_BIT, // THe map bits must be in the same sequence as the enum names for the map channels @@ -73,12 +73,12 @@ public: NUM_MAP_CHANNELS, }; - enum AlphaMapMode { - ALPHA_MAP_OPAQUE = 0, - ALPHA_MAP_MASK, - ALPHA_MAP_BLEND, + enum OpacityMapMode { + OPACITY_MAP_OPAQUE = 0, + OPACITY_MAP_MASK, + OPACITY_MAP_BLEND, }; - static std::string getAlphaMapModeName(AlphaMapMode mode); + static std::string getOpacityMapModeName(OpacityMapMode mode); // The signature is the Flags Flags _flags; @@ -101,8 +101,26 @@ public: Builder& withGlossy() { _flags.set(GLOSSY_VAL_BIT); return (*this); } Builder& withTranslucentFactor() { _flags.set(OPACITY_VAL_BIT); return (*this); } - - Builder& withAlphaCutoff() { _flags.set(ALPHA_CUTOFF_VAL_BIT); return (*this); } + Builder& withTranslucentMap() { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } + Builder& withMaskMap() { _flags.set(OPACITY_MASK_MAP_BIT); return (*this); } + Builder& withOpacityMapMode(OpacityMapMode mode) { + switch (mode) { + case OPACITY_MAP_OPAQUE: + _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.reset(OPACITY_MASK_MAP_BIT); + break; + case OPACITY_MAP_MASK: + _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.set(OPACITY_MASK_MAP_BIT); + break; + case OPACITY_MAP_BLEND: + _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); + _flags.reset(OPACITY_MASK_MAP_BIT); + break; + }; + return (*this); + } + Builder& withOpacityCutoff() { _flags.set(OPACITY_CUTOFF_VAL_BIT); return (*this); } Builder& withScattering() { _flags.set(SCATTERING_VAL_BIT); return (*this); } @@ -111,26 +129,6 @@ public: Builder& withMetallicMap() { _flags.set(METALLIC_MAP_BIT); return (*this); } Builder& withRoughnessMap() { _flags.set(ROUGHNESS_MAP_BIT); return (*this); } - Builder& withTranslucentMap() { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } - Builder& withMaskMap() { _flags.set(OPACITY_MASK_MAP_BIT); return (*this); } - Builder& withAlphaMapMode(AlphaMapMode mode) { - switch (mode) { - case ALPHA_MAP_OPAQUE: - _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); - _flags.reset(OPACITY_MASK_MAP_BIT); - break; - case ALPHA_MAP_MASK: - _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); - _flags.set(OPACITY_MASK_MAP_BIT); - break; - case ALPHA_MAP_BLEND: - _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); - _flags.reset(OPACITY_MASK_MAP_BIT); - break; - }; - return (*this); - } - Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); } Builder& withOcclusionMap() { _flags.set(OCCLUSION_MAP_BIT); return (*this); } Builder& withLightMap() { _flags.set(LIGHT_MAP_BIT); return (*this); } @@ -171,15 +169,15 @@ public: void setTranslucentFactor(bool value) { _flags.set(OPACITY_VAL_BIT, value); } bool isTranslucentFactor() const { return _flags[OPACITY_VAL_BIT]; } - void setAlphaCutoff(bool value) { _flags.set(ALPHA_CUTOFF_VAL_BIT, value); } - bool isAlphaCutoff() const { return _flags[ALPHA_CUTOFF_VAL_BIT]; } - void setTranslucentMap(bool value) { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT, value); } bool isTranslucentMap() const { return _flags[OPACITY_TRANSLUCENT_MAP_BIT]; } void setOpacityMaskMap(bool value) { _flags.set(OPACITY_MASK_MAP_BIT, value); } bool isOpacityMaskMap() const { return _flags[OPACITY_MASK_MAP_BIT]; } + void setOpacityCutoff(bool value) { _flags.set(OPACITY_CUTOFF_VAL_BIT, value); } + bool isOpacityCutoff() const { return _flags[OPACITY_CUTOFF_VAL_BIT]; } + void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); } bool isNormalMap() const { return _flags[NORMAL_MAP_BIT]; } @@ -200,23 +198,23 @@ public: // Translucency and Opacity Heuristics are combining several flags: - void setAlphaMapMode(AlphaMapMode mode) { + void setOpacityMapMode(OpacityMapMode mode) { switch (mode) { - case ALPHA_MAP_OPAQUE: + case OPACITY_MAP_OPAQUE: _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); _flags.reset(OPACITY_MASK_MAP_BIT); break; - case ALPHA_MAP_MASK: + case OPACITY_MAP_MASK: _flags.reset(OPACITY_TRANSLUCENT_MAP_BIT); _flags.set(OPACITY_MASK_MAP_BIT); break; - case ALPHA_MAP_BLEND: + case OPACITY_MAP_BLEND: _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); _flags.reset(OPACITY_MASK_MAP_BIT); break; }; } - AlphaMapMode getAlphaMapMode() const { return (isOpacityMaskMap() ? ALPHA_MAP_MASK : (isTranslucentMap() ? ALPHA_MAP_BLEND : ALPHA_MAP_OPAQUE)); } + OpacityMapMode getOpacityMapMode() const { return (isOpacityMaskMap() ? OPACITY_MAP_MASK : (isTranslucentMap() ? OPACITY_MAP_BLEND : OPACITY_MAP_OPAQUE)); } bool isTranslucent() const { return isTranslucentFactor() || isTranslucentMap(); } bool isOpaque() const { return !isTranslucent(); } @@ -270,15 +268,15 @@ public: Builder& withoutTranslucentFactor() { _value.reset(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); } Builder& withTranslucentFactor() { _value.set(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); } - Builder& withoutAlphaCutoff() { _value.reset(MaterialKey::ALPHA_CUTOFF_VAL_BIT); _mask.set(MaterialKey::ALPHA_CUTOFF_VAL_BIT); return (*this); } - Builder& withAlphaCutoff() { _value.set(MaterialKey::ALPHA_CUTOFF_VAL_BIT); _mask.set(MaterialKey::ALPHA_CUTOFF_VAL_BIT); return (*this); } - Builder& withoutTranslucentMap() { _value.reset(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } Builder& withTranslucentMap() { _value.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT); return (*this); } Builder& withoutMaskMap() { _value.reset(MaterialKey::OPACITY_MASK_MAP_BIT); _mask.set(MaterialKey::OPACITY_MASK_MAP_BIT); return (*this); } Builder& withMaskMap() { _value.set(MaterialKey::OPACITY_MASK_MAP_BIT); _mask.set(MaterialKey::OPACITY_MASK_MAP_BIT); return (*this); } + Builder& withoutOpacityCutoff() { _value.reset(MaterialKey::OPACITY_CUTOFF_VAL_BIT); _mask.set(MaterialKey::OPACITY_CUTOFF_VAL_BIT); return (*this); } + Builder& withOpacityCutoff() { _value.set(MaterialKey::OPACITY_CUTOFF_VAL_BIT); _mask.set(MaterialKey::OPACITY_CUTOFF_VAL_BIT); return (*this); } + Builder& withoutNormalMap() { _value.reset(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); } Builder& withNormalMap() { _value.set(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); } @@ -333,13 +331,13 @@ public: void setOpacity(float opacity); float getOpacity() const { return _opacity; } - static const MaterialKey::AlphaMapMode DEFAULT_ALPHA_MAP_MODE; - void setAlphaMapMode(MaterialKey::AlphaMapMode alphaMode); - MaterialKey::AlphaMapMode getAlphaMapMode() const; + static const MaterialKey::OpacityMapMode DEFAULT_OPACITY_MAP_MODE; + void setOpacityMapMode(MaterialKey::OpacityMapMode alphaMode); + MaterialKey::OpacityMapMode getOpacityMapMode() const; - static const float DEFAULT_ALPHA_CUTOFF; - void setAlphaCutoff(float alphaCutoff); - float getAlphaCutoff() const { return _alphaCutoff; } + static const float DEFAULT_OPACITY_CUTOFF; + void setOpacityCutoff(float opacityCutoff); + float getOpacityCutoff() const { return _opacityCutoff; } void setUnlit(bool value); bool isUnlit() const { return _key.isUnlit(); } @@ -416,7 +414,7 @@ private: float _roughness { DEFAULT_ROUGHNESS }; float _metallic { DEFAULT_METALLIC }; float _scattering { DEFAULT_SCATTERING }; - float _alphaCutoff { DEFAULT_ALPHA_CUTOFF }; + float _opacityCutoff { DEFAULT_OPACITY_CUTOFF }; std::array _texcoordTransforms; glm::vec2 _lightmapParams { 0.0, 1.0 }; glm::vec2 _materialParams { 0.0, 1.0 }; @@ -485,7 +483,7 @@ public: float _metallic { Material::DEFAULT_METALLIC }; // Not Metallic float _scattering { Material::DEFAULT_SCATTERING }; // Scattering info - float _alphaCutoff { Material::DEFAULT_ALPHA_CUTOFF }; // Alpha cutoff applyed when using alphaMa as Mask + float _opacityCutoff { Material::DEFAULT_OPACITY_CUTOFF }; // Opacity cutoff applyed when using opacityMap as Mask uint32_t _key { 0 }; // a copy of the materialKey // Texture Coord Transform Array diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index 76847c081f..fa2c4d0aa9 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -49,7 +49,7 @@ struct TexMapArray { struct Material { vec4 _emissiveOpacity; vec4 _albedoRoughness; - vec4 _metallicScatteringAlphaCutoffKey; + vec4 _metallicScatteringOpacityCutoffKey; }; LAYOUT_STD140(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer { @@ -71,11 +71,11 @@ vec3 getMaterialAlbedo(Material m) { return m._albedoRoughness.rgb; } float getMaterialRoughness(Material m) { return m._albedoRoughness.a; } float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); } -float getMaterialMetallic(Material m) { return m._metallicScatteringAlphaCutoffKey.x; } -float getMaterialScattering(Material m) { return m._metallicScatteringAlphaCutoffKey.y; } -float getMaterialAlphaCutoff(Material m) { return m._metallicScatteringAlphaCutoffKey.z; } +float getMaterialMetallic(Material m) { return m._metallicScatteringOpacityCutoffKey.x; } +float getMaterialScattering(Material m) { return m._metallicScatteringOpacityCutoffKey.y; } +float getMaterialOpacityCutoff(Material m) { return m._metallicScatteringOpacityCutoffKey.z; } -BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._metallicScatteringAlphaCutoffKey.w); } +BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._metallicScatteringOpacityCutoffKey.w); } const BITFIELD EMISSIVE_VAL_BIT = 0x00000001; const BITFIELD UNLIT_VAL_BIT = 0x00000002; @@ -85,7 +85,7 @@ const BITFIELD GLOSSY_VAL_BIT = 0x00000010; const BITFIELD OPACITY_VAL_BIT = 0x00000020; const BITFIELD OPACITY_MASK_MAP_BIT = 0x00000040; const BITFIELD OPACITY_TRANSLUCENT_MAP_BIT = 0x00000080; -const BITFIELD ALPHA_CUTOFF_VAL_BIT = 0x00000100; +const BITFIELD OPACITY_CUTOFF_VAL_BIT = 0x00000100; const BITFIELD SCATTERING_VAL_BIT = 0x00000200; diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index 93b90cc591..2a291e5d57 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -214,21 +214,22 @@ vec3 fetchLightMap(vec2 uv) { } <@endfunc@> -<@func evalMaterialOpacityMask(fetchedOpacity, materialAlphaCutoff, opacity)@> +<@func evalMaterialOpacityMask(fetchedOpacity, materialOpacityCutoff, opacity)@> { - <$opacity$> = step(<$materialAlphaCutoff$>, <$fetchedOpacity$>); + // This path only valid for opaque or texel opaque material + <$opacity$> = step(<$materialOpacityCutoff$>, <$fetchedOpacity$>); } <@endfunc@> -<@func evalMaterialOpacity(fetchedOpacity, materialOpacity, matKey, opacity)@> +<@func evalMaterialOpacity(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@> { - const float OPACITY_MASK_THRESHOLD = 0.5; - <$opacity$> = mix(1.0, - mix(<$fetchedOpacity$>, - step(OPACITY_MASK_THRESHOLD, <$fetchedOpacity$>), - float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0)), - float((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0)) * <$materialOpacity$>; + // This path only valid for transparent material + // Assert that float((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0)) == 1.0 + <$opacity$> = mix(<$fetchedOpacity$>, + step(<$materialOpacityCutoff$>, <$fetchedOpacity$>), + float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0)) + * <$materialOpacity$>; } <@endfunc@> diff --git a/libraries/material-networking/src/material-networking/MaterialCache.cpp b/libraries/material-networking/src/material-networking/MaterialCache.cpp index 41ea04135b..dd55b7fd86 100644 --- a/libraries/material-networking/src/material-networking/MaterialCache.cpp +++ b/libraries/material-networking/src/material-networking/MaterialCache.cpp @@ -258,6 +258,22 @@ std::pair> NetworkMaterialResource } else if (value.isDouble()) { material->setMetallic(value.toDouble()); } + } else if (key == "opacityCuttoff") { + auto value = materialJSON.value(key); + if (value.isString() && value.toString() == FALLTHROUGH) { + material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::OPACITY_CUTOFF_VAL_BIT); + } + else if (value.isDouble()) { + material->setOpacityCutoff(value.toDouble()); + } + /* SG TODO: Implement the set opacityMapMOde intentionaly } else if (key == "opacityMapMode") { + auto value = materialJSON.value(key); + if (value.isString() && value.toString() == FALLTHROUGH) { + material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::OPACITY_MAP_MODE_BIT); + } + else if (value.isDouble()) { + material->setOpacityCutoff(value.toDouble()); + }**/ } else if (key == "scattering") { auto value = materialJSON.value(key); if (value.isString() && value.toString() == FALLTHROUGH) { diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index 2d9cb6c654..bf3ec82bbc 100644 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -103,11 +103,12 @@ void main(void) { <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$> <@if HIFI_USE_TRANSLUCENT@> + float cutoff = getMaterialOpacityCutoff(mat); float opacity = getMaterialOpacity(mat) * _color.a; - <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; + <$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>; <$discardInvisible(opacity)$>; <@else@> - float cutoff = getMaterialAlphaCutoff(mat); + float cutoff = getMaterialOpacityCutoff(mat); float opacity = 1.0; <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>; <$discardTransparent(opacity)$>; @@ -154,6 +155,7 @@ void main(void) { <@endif@> <@if HIFI_USE_TRANSLUCENT@> + float cutoff = getMaterialOpacityCutoff(mat); float opacity = getMaterialOpacity(mat) * _color.a; <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; <$discardInvisible(opacity)$>; @@ -215,13 +217,13 @@ void main(void) { _fragColor0 = color; <@else@> _fragColor0 = vec4(evalLightmappedColor( - cam._viewInverse, - 1.0, - DEFAULT_OCCLUSION, - fragNormalWS, - albedo, - lightmap), - opacity); + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragNormalWS, + albedo, + lightmap), + opacity); <@endif@> <@else@> <@if not HIFI_USE_LIGHTMAP@> @@ -239,13 +241,13 @@ void main(void) { opacity); <@else@> _fragColor0 = vec4(evalLightmappedColor( - cam._viewInverse, - 1.0, - DEFAULT_OCCLUSION, - fragNormalWS, - albedo, - lightmap), - opacity); + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragNormalWS, + albedo, + lightmap), + opacity); <@endif@> <@endif@> <@else@> @@ -313,13 +315,13 @@ void main(void) { opacity); <@else@> _fragColor0 = vec4(evalLightmappedColor( - cam._viewInverse, - 1.0, - DEFAULT_OCCLUSION, - fragNormalWS, - albedo, - lightmap), - opacity); + cam._viewInverse, + 1.0, + DEFAULT_OCCLUSION, + fragNormalWS, + albedo, + lightmap), + opacity); <@endif@> <@endif@> <@endif@> diff --git a/scripts/developer/utilities/cache/cash.js b/scripts/developer/utilities/cache/cash.js index 2181a50c36..14ecf873e3 100644 --- a/scripts/developer/utilities/cache/cash.js +++ b/scripts/developer/utilities/cache/cash.js @@ -1,11 +1,11 @@ "use strict"; -var Page = Script.require('./cash/Page.js'); +var Page = Script.require('../lib/skit/Page.js'); function openView() { //window.closed.connect(function() { Script.stop(); }); - var pages = new Pages(); + var pages = new Pages(Script.resolvePath(".")); function fromQml(message) { console.log(JSON.stringify(message)) if (message.method == "inspectResource") { @@ -40,13 +40,13 @@ function openView() { } - pages.addPage('Cash', 'Cash', "../cash.qml", 300, 500, fromQml, openCashWindow, closeCashWindow); - pages.addPage('openModelCacheInspector', 'Model Cache Inspector', "./ModelCacheInspector.qml", 300, 500, fromQml); - pages.addPage('openMaterialCacheInspector', 'Material Cache Inspector', "./MaterialCacheInspector.qml", 300, 500, fromQml); - pages.addPage('openTextureCacheInspector', 'Texture Cache Inspector', "./TextureCacheInspector.qml", 300, 500, fromQml); - pages.addPage('openAnimationCacheInspector', 'Animation Cache Inspector', "./AnimationCacheInspector.qml", 300, 500); - pages.addPage('openSoundCacheInspector', 'Sound Cache Inspector', "./SoundCacheInspector.qml", 300, 500); - pages.addPage('openResourceInspector', 'Resource Inspector', "./ResourceInspector.qml", 300, 500); + pages.addPage('Cash', 'Cash', "cash.qml", 300, 500, fromQml, openCashWindow, closeCashWindow); + pages.addPage('openModelCacheInspector', 'Model Cache Inspector', "cash/ModelCacheInspector.qml", 300, 500, fromQml); + pages.addPage('openMaterialCacheInspector', 'Material Cache Inspector', "cash/MaterialCacheInspector.qml", 300, 500, fromQml); + pages.addPage('openTextureCacheInspector', 'Texture Cache Inspector', "cash/TextureCacheInspector.qml", 300, 500, fromQml); + pages.addPage('openAnimationCacheInspector', 'Animation Cache Inspector', "cash/AnimationCacheInspector.qml", 300, 500); + pages.addPage('openSoundCacheInspector', 'Sound Cache Inspector', "cash/SoundCacheInspector.qml", 300, 500); + pages.addPage('openResourceInspector', 'Resource Inspector', "cash/ResourceInspector.qml", 300, 500); pages.open('Cash'); diff --git a/scripts/developer/utilities/cache/cash/Page.js b/scripts/developer/utilities/lib/skit/Page.js similarity index 89% rename from scripts/developer/utilities/cache/cash/Page.js rename to scripts/developer/utilities/lib/skit/Page.js index d24af3d1ba..189c26044a 100644 --- a/scripts/developer/utilities/cache/cash/Page.js +++ b/scripts/developer/utilities/lib/skit/Page.js @@ -12,7 +12,7 @@ (function() { function Page(title, qmlurl, width, height, onFromQml, onViewCreated, onViewClosed) { this.title = title; - this.qml = qmlurl; + this.qmlurl = qmlurl; this.width = width; this.height = height; this.onFromQml = onFromQml; @@ -43,7 +43,7 @@ Page.prototype.createView = function () { var that = this; if (!this.window) { print("Page: New window for page:" + this.title); - this.window = Desktop.createWindow(Script.resolvePath(this.qml), { + this.window = Desktop.createWindow(this.qmlurl, { title: this.title, presentationMode: Desktop.PresentationMode.NATIVE, size: {x: this.width, y: this.height} @@ -60,7 +60,9 @@ Page.prototype.createView = function () { }; -Pages = function () { +Pages = function (relativePath) { + print(relativePath) + this._relativePath = relativePath this._pages = {}; }; @@ -73,7 +75,7 @@ Pages.prototype.addPage = function (command, title, qmlurl, width, height, onFro // Workaround for bad linter onViewClosed = function() {}; } - this._pages[command] = new Page(title, qmlurl, width, height, onFromQml, onViewCreated, onViewClosed); + this._pages[command] = new Page(title, Script.resolvePath(this._relativePath + qmlurl), width, height, onFromQml, onViewCreated, onViewClosed); }; Pages.prototype.open = function (command) { diff --git a/scripts/developer/utilities/render/luci.js b/scripts/developer/utilities/render/luci.js index e2e5523ccd..3b832bdfb4 100644 --- a/scripts/developer/utilities/render/luci.js +++ b/scripts/developer/utilities/render/luci.js @@ -1,14 +1,13 @@ var MaterialInspector = Script.require('./materialInspector.js'); -var Page = Script.require('./luci/Page.js'); + +var Page = Script.require('../lib/skit/Page.js'); function openView() { - //window.closed.connect(function() { Script.stop(); }); + var pages = new Pages(Script.resolvePath(".")); - - var pages = new Pages(); function fromQml(message) { if (pages.open(message.method)) { return; @@ -17,12 +16,6 @@ function openView() { var luciWindow function openLuciWindow(window) { - if (luciWindow !== undefined) { - activeWindow.fromQml.disconnect(fromQml); - } - if (window !== undefined) { - window.fromQml.connect(fromQml); - } luciWindow = window; @@ -57,9 +50,6 @@ function openView() { } function closeLuciWindow() { - if (luciWindow !== undefined) { - activeWindow.fromQml.disconnect(fromQml); - } luciWindow = {}; Controller.mousePressEvent.disconnect(onMousePressEvent); @@ -68,10 +58,10 @@ function openView() { pages.clear(); } - pages.addPage('Luci', 'Luci', '../luci.qml', 300, 420, openLuciWindow, closeLuciWindow); - pages.addPage('openEngineInspectorView', 'Render Engine Inspector', '../engineInspector.qml', 300, 400); - pages.addPage('openEngineLODView', 'Render LOD', '../lod.qml', 300, 400); - pages.addPage('openMaterialInspectorView', 'Material Inspector', '../materialInspector.qml', 300, 400, MaterialInspector.setWindow, MaterialInspector.setWindow); + pages.addPage('Luci', 'Luci', 'luci.qml', 300, 420, fromQml, openLuciWindow, closeLuciWindow); + pages.addPage('openEngineInspectorView', 'Render Engine Inspector', 'engineInspector.qml', 300, 400); + pages.addPage('openEngineLODView', 'Render LOD', 'lod.qml', 300, 400); + pages.addPage('openMaterialInspectorView', 'Material Inspector', 'materialInspector.qml', 300, 400, null, MaterialInspector.setWindow, MaterialInspector.setWindow); pages.open('Luci'); diff --git a/scripts/developer/utilities/render/luci/Page.js b/scripts/developer/utilities/render/luci/Page.js deleted file mode 100644 index 06c9704abf..0000000000 --- a/scripts/developer/utilities/render/luci/Page.js +++ /dev/null @@ -1,90 +0,0 @@ -// -// Page.js -// -// Sam Gateau, created on 4/19/2019 -// Copyright 2019 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 -// -"use strict"; - -(function() { -function Page(title, qmlurl, width, height, onViewCreated, onViewClosed) { - this.title = title; - this.qml = qmlurl; - this.width = width; - this.height = height; - this.onViewCreated = onViewCreated; - this.onViewClosed = onViewClosed; - - this.window; - - print("Page: New Page:" + JSON.stringify(this)); -} - -Page.prototype.killView = function () { - print("Page: Kill window for page:" + JSON.stringify(this)); - if (this.window) { - print("Page: Kill window for page:" + this.title); - //this.window.closed.disconnect(function () { - // this.killView(); - //}); - this.window.close(); - this.window = false; - } -}; - -Page.prototype.createView = function () { - var that = this; - if (!this.window) { - print("Page: New window for page:" + this.title); - this.window = Desktop.createWindow(Script.resolvePath(this.qml), { - title: this.title, - presentationMode: Desktop.PresentationMode.NATIVE, - size: {x: this.width, y: this.height} - }); - this.onViewCreated(this.window); - this.window.closed.connect(function () { - that.killView(); - that.onViewClosed(); - }); - } -}; - - -Pages = function () { - this._pages = {}; -}; - -Pages.prototype.addPage = function (command, title, qmlurl, width, height, onViewCreated, onViewClosed) { - if (onViewCreated === undefined) { - // Workaround for bad linter - onViewCreated = function(window) {}; - } - if (onViewClosed === undefined) { - // Workaround for bad linter - onViewClosed = function() {}; - } - this._pages[command] = new Page(title, qmlurl, width, height, onViewCreated, onViewClosed); -}; - -Pages.prototype.open = function (command) { - print("Pages: command = " + command); - if (!this._pages[command]) { - print("Pages: unknown command = " + command); - return; - } - this._pages[command].createView(); -}; - -Pages.prototype.clear = function () { - for (var p in this._pages) { - print("Pages: kill page: " + p); - this._pages[p].killView(); - delete this._pages[p]; - } - this._pages = {}; -}; - -}()); From 4d94cbe0d891fccf87ac9c2e708c92090bc8c929 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 27 Sep 2019 00:29:10 -0700 Subject: [PATCH 17/21] Pass 3rd of the hope to clean it up... --- .../GraphicsScriptingInterface.cpp | 2 +- .../graphics-scripting/ScriptableModel.cpp | 8 +++--- libraries/graphics/src/graphics/Material.cpp | 27 ++++++++++--------- .../render-utils/src/RenderPipelines.cpp | 10 +++---- libraries/render-utils/src/model.slf | 4 +-- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp index ef3172119c..ca9634e365 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp @@ -428,7 +428,7 @@ namespace scriptable { if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_CUTOFF_VAL_BIT)) { obj.setProperty("opacityCutoff", FALLTHROUGH); - } else if (!material.key.isOpacityCutoff()) { + } else if (material.key.isOpacityCutoff()) { obj.setProperty("opacityCutoff", material.opacityCutoff); } diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp index 4f656d2d7d..bc610108ec 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp @@ -26,7 +26,7 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const roughness = material.roughness; metallic = material.metallic; scattering = material.scattering; - alphaCutoff = material.alphaCutoff; + opacityCutoff = material.opacityCutoff; unlit = material.unlit; emissive = material.emissive; albedo = material.albedo; @@ -42,7 +42,7 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const occlusionMap = material.occlusionMap; lightMap = material.lightMap; scatteringMap = material.scatteringMap; - opacityMode = material.opacityMode; + opacityMapMode = material.opacityMapMode; defaultFallthrough = material.defaultFallthrough; @@ -59,11 +59,11 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint model = material->getModel().c_str(); opacity = material->getOpacity(); - opacityMode = QString(graphics::MaterialKey::getAlphaMapModeName(material->getAlphaMapMode()).c_str()); + opacityMapMode = QString(graphics::MaterialKey::getOpacityMapModeName(material->getOpacityMapMode()).c_str()); roughness = material->getRoughness(); metallic = material->getMetallic(); scattering = material->getScattering(); - alphaCutoff = material->getAlphaCutoff(); + opacityCutoff = material->getOpacityCutoff(); unlit = material->isUnlit(); emissive = material->getEmissive(); albedo = material->getAlbedo(); diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index 48ff31e739..ed98b1a1e4 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -25,11 +25,12 @@ const float Material::DEFAULT_ALBEDO { 0.5f }; const float Material::DEFAULT_METALLIC { 0.0f }; const float Material::DEFAULT_ROUGHNESS { 1.0f }; const float Material::DEFAULT_SCATTERING{ 0.0f }; -const float Material::DEFAULT_ALPHA_CUTOFF { 0.5f }; +const MaterialKey::OpacityMapMode Material::DEFAULT_OPACITY_MAP_MODE{ MaterialKey::OPACITY_MAP_OPAQUE }; +const float Material::DEFAULT_OPACITY_CUTOFF { 0.5f }; -std::string MaterialKey::getAlphaMapModeName(AlphaMapMode mode) { - const std::string names[3] = { "ALPHA_MAP_OPAQUE", "ALPHA_MAP_MASK", "ALPHA_MAP_BLEND" }; +std::string MaterialKey::getOpacityMapModeName(OpacityMapMode mode) { + const std::string names[3] = { "OPACITY_MAP_OPAQUE", "OAPCITY_MAP_MASK", "OPACITY_MAP_BLEND" }; return names[mode]; } @@ -49,7 +50,7 @@ Material::Material(const Material& material) : _roughness(material._roughness), _metallic(material._metallic), _scattering(material._scattering), - _alphaCutoff(material._alphaCutoff), + _opacityCutoff(material._opacityCutoff), _texcoordTransforms(material._texcoordTransforms), _lightmapParams(material._lightmapParams), _materialParams(material._materialParams), @@ -71,7 +72,7 @@ Material& Material::operator=(const Material& material) { _roughness = material._roughness; _metallic = material._metallic; _scattering = material._scattering; - _alphaCutoff = material._alphaCutoff; + _opacityCutoff = material._opacityCutoff; _texcoordTransforms = material._texcoordTransforms; _lightmapParams = material._lightmapParams; _materialParams = material._materialParams; @@ -120,18 +121,18 @@ void Material::setScattering(float scattering) { _scattering = scattering; } -void Material::setAlphaCutoff(float alphaCutoff) { - alphaCutoff = glm::clamp(alphaCutoff, 0.0f, 1.0f); - _key.setAlphaCutoff(alphaCutoff != DEFAULT_ALPHA_CUTOFF); - _alphaCutoff = alphaCutoff; +void Material::setOpacityCutoff(float opacityCutoff) { + opacityCutoff = glm::clamp(opacityCutoff, 0.0f, 1.0f); + _key.setOpacityCutoff(opacityCutoff != DEFAULT_OPACITY_CUTOFF); + _opacityCutoff = opacityCutoff; } -void Material::setAlphaMapMode(MaterialKey::AlphaMapMode alphaMode) { - _key.setAlphaMapMode(alphaMode); +void Material::setOpacityMapMode(MaterialKey::OpacityMapMode opacityMapMode) { + _key.setOpacityMapMode(opacityMapMode); } -MaterialKey::AlphaMapMode Material::getAlphaMapMode() const { - return _key.getAlphaMapMode(); +MaterialKey::OpacityMapMode Material::getOpacityMapMode() const { + return _key.getOpacityMapMode(); } void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) { diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 42ff74476f..518e43a8ec 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -461,10 +461,10 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial wasSet = true; } break; - case graphics::MaterialKey::ALPHA_CUTOFF_VAL_BIT: - if (materialKey.isAlphaCutoff()) { - schema._alphaCutoff = material->getAlphaCutoff(); - schemaKey.setAlphaCutoff(true); + case graphics::MaterialKey::OPACITY_CUTOFF_VAL_BIT: + if (materialKey.isOpacityCutoff()) { + schema._opacityCutoff = material->getOpacityCutoff(); + schemaKey.setOpacityCutoff(true); wasSet = true; } break; @@ -759,7 +759,7 @@ bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: // For shadows, we only need opacity mask information auto key = multiMaterial.getMaterialKey(); - if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE || key.isOpacityMaskMap()) { + if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE || (key.isOpacityMaskMap() || key.isTranslucentMap())) { auto& schemaBuffer = multiMaterial.getSchemaBuffer(); batch.setUniformBuffer(gr::Buffer::Material, schemaBuffer); if (enableTextures) { diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index bf3ec82bbc..bacc6b0ab1 100644 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -157,10 +157,10 @@ void main(void) { <@if HIFI_USE_TRANSLUCENT@> float cutoff = getMaterialOpacityCutoff(mat); float opacity = getMaterialOpacity(mat) * _color.a; - <$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>; + <$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>; <$discardInvisible(opacity)$>; <@else@> - float cutoff = getMaterialAlphaCutoff(mat); + float cutoff = getMaterialOpacityCutoff(mat); float opacity = 1.0; <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>; <$discardTransparent(opacity)$>; From 57f80955069a4adfc7e979699bce778f4128a170 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 27 Sep 2019 12:00:45 -0700 Subject: [PATCH 18/21] Pass 4 on cleaning up that pr, put the SortFIlterModel.qml in the new skit/qml lib, setting the opacityMappMode correctly from script --- libraries/graphics/src/graphics/Material.cpp | 18 ++++++++++- libraries/graphics/src/graphics/Material.h | 11 ++++++- libraries/graphics/src/graphics/Material.slh | 21 ++++++------ .../src/material-networking/MaterialCache.cpp | 32 ++++++++++++------- .../cache/cash/ResourceCacheInspector.qml | 3 +- .../developer/utilities/lib/prop/PropItem.qml | 3 -- .../cash => lib/skit/qml}/SortFilterModel.qml | 0 .../developer/utilities/lib/skit/qml/qmldir | 1 + 8 files changed, 62 insertions(+), 27 deletions(-) rename scripts/developer/utilities/{cache/cash => lib/skit/qml}/SortFilterModel.qml (100%) create mode 100644 scripts/developer/utilities/lib/skit/qml/qmldir diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index ed98b1a1e4..5fcf8ba06a 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -30,10 +30,20 @@ const float Material::DEFAULT_OPACITY_CUTOFF { 0.5f }; std::string MaterialKey::getOpacityMapModeName(OpacityMapMode mode) { - const std::string names[3] = { "OPACITY_MAP_OPAQUE", "OAPCITY_MAP_MASK", "OPACITY_MAP_BLEND" }; + const std::string names[3] = { "OPACITY_MAP_OPAQUE", "OPACITY_MAP_MASK", "OPACITY_MAP_BLEND" }; return names[mode]; } + +bool MaterialKey::getOpacityMapModeFromName(const std::string& modeName, MaterialKey::OpacityMapMode& mode) { + for (mode = OPACITY_MAP_OPAQUE; mode <= OPACITY_MAP_BLEND; mode + 1) { + if (modeName == getOpacityMapModeName(mode)) { + return true; + } + } + return false; +} + Material::Material() { for (int i = 0; i < NUM_TOTAL_FLAGS; i++) { _propertyFallthroughs[i] = false; @@ -166,6 +176,12 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur } bool Material::resetOpacityMap() const { + // If OpacityMapMode explicit then nothing need to change here. + if (_key.isOpacityMapMode()) { + return false; + } + + // Else, the legacy behavior is to interpret the albedo texture assigned to tune the opacity map mode value auto previous = _key.getOpacityMapMode(); // Clear the previous flags _key.setOpacityMaskMap(false); diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index d2bb7b77e3..25ff711c0c 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -43,6 +43,7 @@ public: OPACITY_VAL_BIT, OPACITY_MASK_MAP_BIT, // Opacity Map and Opacity MASK map are mutually exclusive OPACITY_TRANSLUCENT_MAP_BIT, + OPACITY_MAP_MODE_BIT, // Opacity map mode bit is set if the value has set explicitely and not deduced from the textures assigned OPACITY_CUTOFF_VAL_BIT, SCATTERING_VAL_BIT, @@ -79,6 +80,8 @@ public: OPACITY_MAP_BLEND, }; static std::string getOpacityMapModeName(OpacityMapMode mode); + // find the enum value from a string, return true if match found + static bool getOpacityMapModeFromName(const std::string& modeName, OpacityMapMode& mode); // The signature is the Flags Flags _flags; @@ -118,6 +121,7 @@ public: _flags.reset(OPACITY_MASK_MAP_BIT); break; }; + _flags.set(OPACITY_MAP_MODE_BIT); // Intentionally set the mode! return (*this); } Builder& withOpacityCutoff() { _flags.set(OPACITY_CUTOFF_VAL_BIT); return (*this); } @@ -213,7 +217,9 @@ public: _flags.reset(OPACITY_MASK_MAP_BIT); break; }; + _flags.set(OPACITY_MAP_MODE_BIT); // Intentionally set the mode! } + bool isOpacityMapMode() const { return _flags[OPACITY_MAP_MODE_BIT]; } OpacityMapMode getOpacityMapMode() const { return (isOpacityMaskMap() ? OPACITY_MAP_MASK : (isTranslucentMap() ? OPACITY_MAP_BLEND : OPACITY_MAP_OPAQUE)); } bool isTranslucent() const { return isTranslucentFactor() || isTranslucentMap(); } @@ -274,6 +280,9 @@ public: Builder& withoutMaskMap() { _value.reset(MaterialKey::OPACITY_MASK_MAP_BIT); _mask.set(MaterialKey::OPACITY_MASK_MAP_BIT); return (*this); } Builder& withMaskMap() { _value.set(MaterialKey::OPACITY_MASK_MAP_BIT); _mask.set(MaterialKey::OPACITY_MASK_MAP_BIT); return (*this); } + Builder& withoutOpacityMapMode() { _value.reset(MaterialKey::OPACITY_MAP_MODE_BIT); _mask.set(MaterialKey::OPACITY_MAP_MODE_BIT); return (*this); } + Builder& withOpacityMapMode() { _value.set(MaterialKey::OPACITY_MAP_MODE_BIT); _mask.set(MaterialKey::OPACITY_MAP_MODE_BIT); return (*this); } + Builder& withoutOpacityCutoff() { _value.reset(MaterialKey::OPACITY_CUTOFF_VAL_BIT); _mask.set(MaterialKey::OPACITY_CUTOFF_VAL_BIT); return (*this); } Builder& withOpacityCutoff() { _value.set(MaterialKey::OPACITY_CUTOFF_VAL_BIT); _mask.set(MaterialKey::OPACITY_CUTOFF_VAL_BIT); return (*this); } @@ -332,7 +341,7 @@ public: float getOpacity() const { return _opacity; } static const MaterialKey::OpacityMapMode DEFAULT_OPACITY_MAP_MODE; - void setOpacityMapMode(MaterialKey::OpacityMapMode alphaMode); + void setOpacityMapMode(MaterialKey::OpacityMapMode opacityMapMode); MaterialKey::OpacityMapMode getOpacityMapMode() const; static const float DEFAULT_OPACITY_CUTOFF; diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index fa2c4d0aa9..328ff4a3af 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -85,17 +85,18 @@ const BITFIELD GLOSSY_VAL_BIT = 0x00000010; const BITFIELD OPACITY_VAL_BIT = 0x00000020; const BITFIELD OPACITY_MASK_MAP_BIT = 0x00000040; const BITFIELD OPACITY_TRANSLUCENT_MAP_BIT = 0x00000080; -const BITFIELD OPACITY_CUTOFF_VAL_BIT = 0x00000100; -const BITFIELD SCATTERING_VAL_BIT = 0x00000200; +const BITFIELD OPACITY_MAP_MODE_BIT = 0x00000100; +const BITFIELD OPACITY_CUTOFF_VAL_BIT = 0x00000200; +const BITFIELD SCATTERING_VAL_BIT = 0x00000400; -const BITFIELD EMISSIVE_MAP_BIT = 0x00000400; -const BITFIELD ALBEDO_MAP_BIT = 0x00000800; -const BITFIELD METALLIC_MAP_BIT = 0x00001000; -const BITFIELD ROUGHNESS_MAP_BIT = 0x00002000; -const BITFIELD NORMAL_MAP_BIT = 0x00004000; -const BITFIELD OCCLUSION_MAP_BIT = 0x00008000; -const BITFIELD LIGHTMAP_MAP_BIT = 0x00010000; -const BITFIELD SCATTERING_MAP_BIT = 0x00020000; +const BITFIELD EMISSIVE_MAP_BIT = 0x00000800; +const BITFIELD ALBEDO_MAP_BIT = 0x00001000; +const BITFIELD METALLIC_MAP_BIT = 0x00002000; +const BITFIELD ROUGHNESS_MAP_BIT = 0x00004000; +const BITFIELD NORMAL_MAP_BIT = 0x00008000; +const BITFIELD OCCLUSION_MAP_BIT = 0x00010000; +const BITFIELD LIGHTMAP_MAP_BIT = 0x00020000; +const BITFIELD SCATTERING_MAP_BIT = 0x00040000; <@endif@> diff --git a/libraries/material-networking/src/material-networking/MaterialCache.cpp b/libraries/material-networking/src/material-networking/MaterialCache.cpp index dd55b7fd86..db4783d249 100644 --- a/libraries/material-networking/src/material-networking/MaterialCache.cpp +++ b/libraries/material-networking/src/material-networking/MaterialCache.cpp @@ -139,6 +139,14 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater * @property {string} opacityMap - The URL of the opacity texture image. Set the value the same as the albedoMap * value for transparency. * "hifi_pbr" model only. + * @property {number|string} opacityMapMode - The mode defining the interpretation of the opacity map. Values can be: + * "OPACITY_MAP_OPAQUE" for ignoring the opacity map information. + * "OPACITY_MAP_MASK" for using the opacity map as a mask, where only the texel greater than opacityCutoff are visible and rendered opaque. + * "OPACITY_MAP_BLEND" for using the opacity map for alpha blending the material surface with the background. + * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. + * @property {number|string} opacityCutoff - The opacity cutoff threshold used to determine the opaque texels of the Opacity map + * when opacityMapMode is "OPACITY_MAP_MASK", range 0.01.0. + * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. * @property {string} roughnessMap - The URL of the roughness texture image. You can use this or glossMap, but not * both. * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. @@ -258,22 +266,24 @@ std::pair> NetworkMaterialResource } else if (value.isDouble()) { material->setMetallic(value.toDouble()); } - } else if (key == "opacityCuttoff") { + } else if (key == "opacityMapMode") { + auto value = materialJSON.value(key); + auto valueString = (value.isString() ? value.toString() : ""); + if (valueString == FALLTHROUGH) { + material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::OPACITY_MAP_MODE_BIT); + } else { + graphics::MaterialKey::OpacityMapMode mode; + if (graphics::MaterialKey::getOpacityMapModeFromName(valueString.toStdString(), mode)) { + material->setOpacityMapMode(mode); + } + } + } else if (key == "opacityCutoff") { auto value = materialJSON.value(key); if (value.isString() && value.toString() == FALLTHROUGH) { material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::OPACITY_CUTOFF_VAL_BIT); - } - else if (value.isDouble()) { + } else if (value.isDouble()) { material->setOpacityCutoff(value.toDouble()); } - /* SG TODO: Implement the set opacityMapMOde intentionaly } else if (key == "opacityMapMode") { - auto value = materialJSON.value(key); - if (value.isString() && value.toString() == FALLTHROUGH) { - material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::OPACITY_MAP_MODE_BIT); - } - else if (value.isDouble()) { - material->setOpacityCutoff(value.toDouble()); - }**/ } else if (key == "scattering") { auto value = materialJSON.value(key); if (value.isString() && value.toString() == FALLTHROUGH) { diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index 7d14a07e13..2fa0af8cbc 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -12,6 +12,7 @@ import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 import QtQml.Models 2.12 +import "../../lib/skit/qml" as Skit import "../../lib/prop" as Prop Item { @@ -313,7 +314,7 @@ Item { } } - SortFilterModel { + Skit.SortFilterModel { id: visualModel model: ListModel {} diff --git a/scripts/developer/utilities/lib/prop/PropItem.qml b/scripts/developer/utilities/lib/prop/PropItem.qml index 24e2ecaa9a..3779e7f4a9 100644 --- a/scripts/developer/utilities/lib/prop/PropItem.qml +++ b/scripts/developer/utilities/lib/prop/PropItem.qml @@ -24,7 +24,6 @@ Item { // By default, these just go get or set the value from the object[property] // function defaultGet() { var v = root.object[root.property]; return v; } - // function defaultGet() { return root.object[root.property]; } function defaultSet(value) { root.object[root.property] = value; } function defaultSetReadOnly(value) {} @@ -36,8 +35,6 @@ Item { height: global.lineHeight anchors.left: parent.left anchors.right: parent.right - // anchors.leftMargin: global.horizontalMargin - // anchors.rightMargin: global.horizontalMargin // LabelControl And SplitterControl are on the left side of the PropItem property bool showLabel: true diff --git a/scripts/developer/utilities/cache/cash/SortFilterModel.qml b/scripts/developer/utilities/lib/skit/qml/SortFilterModel.qml similarity index 100% rename from scripts/developer/utilities/cache/cash/SortFilterModel.qml rename to scripts/developer/utilities/lib/skit/qml/SortFilterModel.qml diff --git a/scripts/developer/utilities/lib/skit/qml/qmldir b/scripts/developer/utilities/lib/skit/qml/qmldir new file mode 100644 index 0000000000..14d11d998a --- /dev/null +++ b/scripts/developer/utilities/lib/skit/qml/qmldir @@ -0,0 +1 @@ +SortFilterModel 1.0 SortFilterModel.qml \ No newline at end of file From ecd940e0e65d8a46b48fbdff743cd1c9cc006e04 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 27 Sep 2019 14:01:00 -0700 Subject: [PATCH 19/21] Addressing warnings --- libraries/graphics/src/graphics/Material.cpp | 3 ++- tools/gpu-frame-player/src/RenderThread.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/graphics/src/graphics/Material.cpp b/libraries/graphics/src/graphics/Material.cpp index 5fcf8ba06a..dffc52e29f 100755 --- a/libraries/graphics/src/graphics/Material.cpp +++ b/libraries/graphics/src/graphics/Material.cpp @@ -36,7 +36,8 @@ std::string MaterialKey::getOpacityMapModeName(OpacityMapMode mode) { bool MaterialKey::getOpacityMapModeFromName(const std::string& modeName, MaterialKey::OpacityMapMode& mode) { - for (mode = OPACITY_MAP_OPAQUE; mode <= OPACITY_MAP_BLEND; mode + 1) { + for (int i = OPACITY_MAP_OPAQUE; i <= OPACITY_MAP_BLEND; i++) { + mode = (MaterialKey::OpacityMapMode) i; if (modeName == getOpacityMapModeName(mode)) { return true; } diff --git a/tools/gpu-frame-player/src/RenderThread.cpp b/tools/gpu-frame-player/src/RenderThread.cpp index 6c0d3c7bba..2a54d186ee 100644 --- a/tools/gpu-frame-player/src/RenderThread.cpp +++ b/tools/gpu-frame-player/src/RenderThread.cpp @@ -182,7 +182,7 @@ void RenderThread::renderFrame(gpu::FramePointer& frame) { batch->setPipeline(_presentPipeline); batch->setFramebuffer(nullptr); batch->setResourceTexture(0, frame->framebuffer->getRenderBuffer(0)); - batch->setViewportTransform(ivec4(uvec2(0), ivec2(scale * fboSize.x, scale * fboSize.y))); + batch->setViewportTransform(ivec4(uvec2(0), ivec2(windowSize.width(), windowSize.height()))); batch->draw(gpu::TRIANGLE_STRIP, 4); } glDisable(GL_FRAMEBUFFER_SRGB); From 9b8d159873bf0da968e85015e003c70b17edbdf8 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 30 Sep 2019 09:24:37 -0700 Subject: [PATCH 20/21] remove unused variable --- tools/gpu-frame-player/src/RenderThread.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/gpu-frame-player/src/RenderThread.cpp b/tools/gpu-frame-player/src/RenderThread.cpp index 2a54d186ee..31e154d38c 100644 --- a/tools/gpu-frame-player/src/RenderThread.cpp +++ b/tools/gpu-frame-player/src/RenderThread.cpp @@ -176,7 +176,6 @@ void RenderThread::renderFrame(gpu::FramePointer& frame) { #ifdef USE_GL static gpu::BatchPointer batch = nullptr; - float scale = 1.0; if (!batch) { batch = std::make_shared(); batch->setPipeline(_presentPipeline); From 1e2cab52b9d2d81591a57a518e9563063d7027c0 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 30 Sep 2019 12:55:04 -0700 Subject: [PATCH 21/21] FIx an error, bad copy paste leading to a bug --- libraries/networking/src/ResourceCache.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 259e14c650..4213d92fc0 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -319,7 +319,7 @@ class ScriptableResourceCache : public QObject { /**jsdoc * @property {number} numGlobalQueriesPending - Total number of global queries pending (across all resource managers). Read-only. - * @property {number} numGlobalQueriesLoading - Total number of global queries pending (across all resource managers). Read-only. + * @property {number} numGlobalQueriesLoading - Total number of global queries loading (across all resource managers). Read-only. */ Q_PROPERTY(size_t numGlobalQueriesPending READ getNumGlobalQueriesPending NOTIFY dirty) Q_PROPERTY(size_t numGlobalQueriesLoading READ getNumGlobalQueriesLoading NOTIFY dirty) @@ -398,8 +398,8 @@ private: size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); } size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); } - size_t getNumGlobalQueriesPending() const { return ResourceCache::getLoadingRequestCount(); } - size_t getNumGlobalQueriesLoading() const { return ResourceCache::getPendingRequestCount(); } + size_t getNumGlobalQueriesPending() const { return ResourceCache::getPendingRequestCount(); } + size_t getNumGlobalQueriesLoading() const { return ResourceCache::getLoadingRequestCount(); } }; /// Base class for resources.