diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml index cabea8f6d5..de5e75b7e5 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml @@ -13,6 +13,7 @@ import "../../simplifiedConstants" as SimplifiedConstants import "../../simplifiedControls" as SimplifiedControls import stylesUit 1.0 as HifiStylesUit import QtQuick.Layouts 1.3 +import PerformanceEnums 1.0 Flickable { property string avatarNametagMode: Settings.getValue("simplifiedNametag/avatarNametagMode", "on") @@ -113,16 +114,28 @@ Flickable { SimplifiedControls.RadioButton { id: performanceLow text: "Eco" + checked: Performance.getRefreshRateProfile() === RefreshRate.ECO + onClicked: { + Performance.setRefreshRateProfile(RefreshRate.ECO); + } } SimplifiedControls.RadioButton { id: performanceMedium text: "Interactive" + checked: Performance.getRefreshRateProfile() === RefreshRate.INTERACTIVE + onClicked: { + Performance.setRefreshRateProfile(RefreshRate.INTERACTIVE); + } } SimplifiedControls.RadioButton { id: performanceHigh text: "Realtime" + checked: Performance.getRefreshRateProfile() === RefreshRate.REALTIME + onClicked: { + Performance.setRefreshRateProfile(RefreshRate.REALTIME); + } } } } diff --git a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml index 6622da33d9..a5a079b4dc 100644 --- a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml +++ b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml @@ -277,8 +277,34 @@ Rectangle { } onClicked: { Tablet.playSound(TabletEnums.ButtonClick); - // TODO: actually do this right and change the display plugin - HMD.active = !HMD.active; + var displayPluginCount = Window.getDisplayPluginCount(); + if (HMD.active) { + // This next line seems backwards and shouldn't be necessary - the NOTIFY handler should + // result in `displayModeImage.source` changing automatically - but that's not working. + // This is working. So, I'm keeping it. + displayModeImage.source = "./images/vrMode.svg"; + + // Switch to desktop mode - selects first VR display plugin + for (var i = 0; i < displayPluginCount; i++) { + if (!Window.isDisplayPluginHmd(i)) { + Window.setActiveDisplayPlugin(i); + return; + } + } + } else { + // This next line seems backwards and shouldn't be necessary - the NOTIFY handler should + // result in `displayModeImage.source` changing automatically - but that's not working. + // This is working. So, I'm keeping it. + displayModeImage.source = "./images/desktopMode.svg"; + + // Switch to VR mode - selects first HMD display plugin + for (var i = 0; i < displayPluginCount; i++) { + if (Window.isDisplayPluginHmd(i)) { + Window.setActiveDisplayPlugin(i); + return; + } + } + } } } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c304b86aa5..48e626d030 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -194,8 +194,7 @@ #include "scripting/TTSScriptingInterface.h" #include "scripting/KeyboardScriptingInterface.h" #include "scripting/PerformanceScriptingInterface.h" - - +#include "scripting/RenderScriptingInterface.h" #if defined(Q_OS_MAC) || defined(Q_OS_WIN) #include "SpeechRecognizer.h" @@ -3331,7 +3330,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { surfaceContext->setContextProperty("LODManager", DependencyManager::get().data()); surfaceContext->setContextProperty("HMD", DependencyManager::get().data()); surfaceContext->setContextProperty("Scene", DependencyManager::get().data()); - surfaceContext->setContextProperty("Render", _graphicsEngine.getRenderEngine()->getConfiguration().get()); + surfaceContext->setContextProperty("Render", RenderScriptingInterface::getInstance()); surfaceContext->setContextProperty("Workload", _gameWorkload._engine->getConfiguration().get()); surfaceContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface()); surfaceContext->setContextProperty("Snapshot", DependencyManager::get().data()); @@ -3446,7 +3445,7 @@ void Application::setupQmlSurface(QQmlContext* surfaceContext, bool setAdditiona surfaceContext->setContextProperty("InputConfiguration", DependencyManager::get().data()); surfaceContext->setContextProperty("SoundCache", DependencyManager::get().data()); surfaceContext->setContextProperty("AvatarBookmarks", DependencyManager::get().data()); - surfaceContext->setContextProperty("Render", AbstractViewStateInterface::instance()->getRenderEngine()->getConfiguration().get()); + surfaceContext->setContextProperty("Render", RenderScriptingInterface::getInstance()); surfaceContext->setContextProperty("Workload", qApp->getGameWorkload()._engine->getConfiguration().get()); surfaceContext->setContextProperty("Controller", DependencyManager::get().data()); surfaceContext->setContextProperty("Pointers", DependencyManager::get().data()); @@ -7396,7 +7395,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerFunction("HMD", "getHUDLookAtPosition3D", HMDScriptingInterface::getHUDLookAtPosition3D, 0); scriptEngine->registerGlobalObject("Scene", DependencyManager::get().data()); - scriptEngine->registerGlobalObject("Render", _graphicsEngine.getRenderEngine()->getConfiguration().get()); + scriptEngine->registerGlobalObject("Render", RenderScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("Workload", _gameWorkload._engine->getConfiguration().get()); GraphicsScriptingInterface::registerMetaTypes(scriptEngine.data()); diff --git a/interface/src/Application.h b/interface/src/Application.h index 17871aadcf..210039beba 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -290,7 +290,6 @@ public: render::EnginePointer getRenderEngine() override { return _graphicsEngine.getRenderEngine(); } gpu::ContextPointer getGPUContext() const { return _graphicsEngine.getGPUContext(); } - const GameWorkload& getGameWorkload() const { return _gameWorkload; } virtual void pushPostUpdateLambda(void* key, const std::function& func) override; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c010a755e9..6b9030e337 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -524,7 +524,7 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ComputeBlendshapes, 0, true, DependencyManager::get().data(), SLOT(setComputeBlendshapes(bool))); - action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::MeshShaders, 0, true); + action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::MeshShaders, 0, false); connect(action, &QAction::triggered, [action] { MeshPartPayload::enableMeshShaders = action->isChecked(); }); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 639f07523d..d7214b8620 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -228,7 +228,7 @@ namespace MenuOption { const QString NotificationSoundsTablet = "play_notification_sounds_tablet"; const QString ForceCoarsePicking = "Force Coarse Picking"; const QString ComputeBlendshapes = "Compute Blendshapes"; - const QString MeshShaders = "Enable Shaders on Meshes"; + const QString MeshShaders = "Enable Procedural Materials on Meshes"; } #endif // hifi_Menu_h diff --git a/interface/src/scripting/RenderScriptingInterface.cpp b/interface/src/scripting/RenderScriptingInterface.cpp new file mode 100644 index 0000000000..8581c7527d --- /dev/null +++ b/interface/src/scripting/RenderScriptingInterface.cpp @@ -0,0 +1,44 @@ +// +// Created by Sam Gondelman on 5/16/19 +// Copyright 2013-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 "RenderScriptingInterface.h" + +const QString DEFERRED = "deferred"; +const QString FORWARD = "forward"; + +RenderScriptingInterface* RenderScriptingInterface::getInstance() { + static RenderScriptingInterface sharedInstance; + return &sharedInstance; +} + +RenderScriptingInterface::RenderScriptingInterface() { + setRenderMethod((render::Args::RenderMethod)_renderMethodSetting.get() == render::Args::RenderMethod::DEFERRED ? DEFERRED : FORWARD); +} + +QString RenderScriptingInterface::getRenderMethod() { + return (render::Args::RenderMethod)_renderMethodSetting.get() == render::Args::RenderMethod::DEFERRED ? DEFERRED : FORWARD; +} + +void RenderScriptingInterface::setRenderMethod(const QString& renderMethod) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setRenderMethod", Q_ARG(const QString&, renderMethod)); + return; + } + + auto config = dynamic_cast(qApp->getRenderEngine()->getConfiguration()->getConfig("RenderMainView.DeferredForwardSwitch")); + if (config) { + if (renderMethod == DEFERRED) { + _renderMethodSetting.set(render::Args::RenderMethod::DEFERRED); + config->setBranch(render::Args::RenderMethod::DEFERRED); + emit config->dirtyEnabled(); + } else if (renderMethod == FORWARD) { + _renderMethodSetting.set(render::Args::RenderMethod::FORWARD); + config->setBranch(render::Args::RenderMethod::FORWARD); + emit config->dirtyEnabled(); + } + } +} \ No newline at end of file diff --git a/interface/src/scripting/RenderScriptingInterface.h b/interface/src/scripting/RenderScriptingInterface.h new file mode 100644 index 0000000000..2aff3a08b6 --- /dev/null +++ b/interface/src/scripting/RenderScriptingInterface.h @@ -0,0 +1,65 @@ +// +// Created by Sam Gondelman on 5/16/19 +// Copyright 2013-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 +// + +#ifndef hifi_RenderScriptingInterface_h +#define hifi_RenderScriptingInterface_h + +#include +#include "Application.h" + +#include "RenderForward.h" + +/**jsdoc + * The Render API allows you to configure the graphics engine + * + * @namespace Render + * + * @hifi-interface + * @hifi-client-entity + * @hifi-avatar + */ +class RenderScriptingInterface : public QObject { + Q_OBJECT + Q_PROPERTY(QString renderMethod READ getRenderMethod WRITE setRenderMethod) + +public: + RenderScriptingInterface(); + + static RenderScriptingInterface* getInstance(); + +public slots: + /**jsdoc + * Get a config for a job by name + * @function Render.getConfig + * @param {string} name - Can be: + * - . Search for the first job named job_name traversing the the sub graph of task and jobs (from this task as root) + * - .[.]. Allows you to first look for the parent_name job (from this task as root) and then search from there for the + * optional sub_parent_names and finally from there looking for the job_name (assuming every job in the path is found) + * @returns {object} The sub job config. + */ + QObject* getConfig(const QString& name) { return qApp->getRenderEngine()->getConfiguration()->getConfig(name); } + + /**jsdoc + * Gets the current render method + * @function Render.getRenderMethod + * @returns {string} "deferred" or "forward" + */ + QString getRenderMethod(); + + /**jsdoc + * Sets the current render method + * @function Render.setRenderMethod + * @param {string} renderMethod - "deferred" or "forward" + */ + void setRenderMethod(const QString& renderMethod); + +private: + Setting::Handle _renderMethodSetting { "renderMethod", RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED }; +}; + +#endif // hifi_RenderScriptingInterface_h diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index ec05ba4319..0f03a2fe29 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -109,7 +109,7 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { withReadLock([&] { auto mat = _materials.find("0"); - if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isEnabled()) { + if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && mat->second.top().material->isEnabled()) { auto procedural = std::static_pointer_cast(mat->second.top().material); if (procedural->isFading()) { procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f); diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index 819365265f..3157a6552b 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -6,5 +6,6 @@ include_hifi_library_headers(fbx) include_hifi_library_headers(gpu) include_hifi_library_headers(image) include_hifi_library_headers(ktx) +include_hifi_library_headers(material-networking) include_hifi_library_headers(procedural) -link_hifi_libraries(shared shaders networking octree avatars graphics material-networking model-networking) +link_hifi_libraries(shared shaders networking octree avatars graphics model-networking) diff --git a/libraries/hfm/src/hfm/HFM.h b/libraries/hfm/src/hfm/HFM.h index 8c60169289..484a10aa3b 100644 --- a/libraries/hfm/src/hfm/HFM.h +++ b/libraries/hfm/src/hfm/HFM.h @@ -291,6 +291,7 @@ public: class Model { public: using Pointer = std::shared_ptr; + using ConstPointer = std::shared_ptr; QString originalURL; QString author; diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index a8e373dc6e..615951345f 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -46,6 +46,7 @@ public: bool isHFMModelLoaded() const { return (bool)_hfmModel; } const HFMModel& getHFMModel() const { return *_hfmModel; } + const HFMModel::ConstPointer& getConstHFMModelPointer() const { return _hfmModel; } const MaterialMapping& getMaterialMapping() const { return _materialMapping; } const GeometryMeshes& getMeshes() const { return *_meshes; } const std::shared_ptr getShapeMaterial(int shapeID) const; @@ -59,7 +60,7 @@ public: protected: // Shared across all geometries, constant throughout lifetime - std::shared_ptr _hfmModel; + HFMModel::ConstPointer _hfmModel; MaterialMapping _materialMapping; std::shared_ptr _meshes; std::shared_ptr _meshParts; diff --git a/libraries/platform/src/AndroidPlatform.cpp b/libraries/platform/src/AndroidPlatform.cpp index e998f6f938..f35674a984 100644 --- a/libraries/platform/src/AndroidPlatform.cpp +++ b/libraries/platform/src/AndroidPlatform.cpp @@ -8,9 +8,8 @@ #include "AndroidPlatform.h" #include "platformJsonKeys.h" - #include -#include + using namespace platform; void AndroidInstance::enumerateCpu() { @@ -35,6 +34,11 @@ void AndroidInstance::enumerateGpu() { void AndroidInstance::enumerateMemory() { json ram = {}; - + ram["totalMemory"]=""; _memory.push_back(ram); } + +void AndroidInstance::enumerateComputer(){ + //no implememntation at this time +} + diff --git a/libraries/platform/src/AndroidPlatform.h b/libraries/platform/src/AndroidPlatform.h index 17efbb45e3..66d80ca1ef 100644 --- a/libraries/platform/src/AndroidPlatform.h +++ b/libraries/platform/src/AndroidPlatform.h @@ -18,6 +18,7 @@ namespace platform { void enumerateCpu() override; void enumerateMemory() override; void enumerateGpu() override; + void enumerateComputer () override; }; } // namespace platform diff --git a/libraries/platform/src/LinuxPlatform.cpp b/libraries/platform/src/LinuxPlatform.cpp index 96c105826f..aa63eb1e08 100644 --- a/libraries/platform/src/LinuxPlatform.cpp +++ b/libraries/platform/src/LinuxPlatform.cpp @@ -9,7 +9,6 @@ #include "LinuxPlatform.h" #include "platformJsonKeys.h" #include -#include using namespace platform; void LinuxInstance::enumerateCpu() { @@ -36,7 +35,12 @@ void LinuxInstance::enumerateGpu() { void LinuxInstance::enumerateMemory() { json ram = {}; - + ram["totalMemory"]=""; _memory.push_back(ram); } + +void LinuxInstance::enumerateComputer(){ + //no implememntation at this time +} + diff --git a/libraries/platform/src/LinuxPlatform.h b/libraries/platform/src/LinuxPlatform.h index 1af4ce7444..63db8557f0 100644 --- a/libraries/platform/src/LinuxPlatform.h +++ b/libraries/platform/src/LinuxPlatform.h @@ -18,6 +18,7 @@ namespace platform { void enumerateCpu() override; void enumerateMemory() override; void enumerateGpu() override; + void enumerateComputer () override; }; } // namespace platform diff --git a/libraries/platform/src/MACOSPlatform.cpp b/libraries/platform/src/MACOSPlatform.cpp index 172cd642aa..7081044879 100644 --- a/libraries/platform/src/MACOSPlatform.cpp +++ b/libraries/platform/src/MACOSPlatform.cpp @@ -8,6 +8,7 @@ #include "MACOSPlatform.h" #include "platformJsonKeys.h" + #include #include #include @@ -15,6 +16,7 @@ #ifdef Q_OS_MAC #include #include +#include #endif using namespace platform; @@ -33,6 +35,7 @@ static void getCpuId( uint32_t* p, uint32_t ax ) #endif } + void MACOSInstance::enumerateCpu() { json cpu = {}; uint32_t cpuInfo[4]={0,0,0,0}; @@ -72,6 +75,7 @@ void MACOSInstance::enumerateGpu() { _gpu.push_back(gpu); _display = ident->getOutput(); + } void MACOSInstance::enumerateMemory() { @@ -84,3 +88,20 @@ void MACOSInstance::enumerateMemory() { #endif _memory.push_back(ram); } + +void MACOSInstance::enumerateComputer(){ +#ifdef Q_OS_MAC + + //get system name + size_t len=0; + sysctlbyname("hw.model",NULL, &len, NULL, 0); + char* model = (char *) malloc(sizeof(char)*len+1); + sysctlbyname("hw.model", model, &len, NULL,0); + + _computer["computerModel"]=std::string(model); + + free(model); + +#endif +} + diff --git a/libraries/platform/src/MACOSPlatform.h b/libraries/platform/src/MACOSPlatform.h index 287e0c0ed7..04b8621698 100644 --- a/libraries/platform/src/MACOSPlatform.h +++ b/libraries/platform/src/MACOSPlatform.h @@ -18,8 +18,9 @@ namespace platform { void enumerateCpu() override; void enumerateMemory() override; void enumerateGpu() override; + void enumerateComputer () override; }; } // namespace platform -#endif //hifi_winplatform_h +#endif //hifi_macosplatform_h diff --git a/libraries/platform/src/WINPlatform.cpp b/libraries/platform/src/WINPlatform.cpp index 601a9d7290..8b37aa4e77 100644 --- a/libraries/platform/src/WINPlatform.cpp +++ b/libraries/platform/src/WINPlatform.cpp @@ -8,6 +8,7 @@ #include "WINPlatform.h" #include "platformJsonKeys.h" + #ifdef Q_OS_WINDOWS #include #include @@ -76,7 +77,12 @@ void WINInstance::enumerateMemory() { statex.dwLength = sizeof(statex); GlobalMemoryStatusEx(&statex); int totalRam = statex.ullTotalPhys / 1024 / 1024; - ram[jsonKeys::totalMemory] = totalRam; + ram["totalMemory"] = totalRam; #endif _memory.push_back(ram); } + +void WINInstance::enumerateComputer(){ + //no implememntation at this time +} + diff --git a/libraries/platform/src/WINPlatform.h b/libraries/platform/src/WINPlatform.h index 4d466a9b7e..828d27ffc3 100644 --- a/libraries/platform/src/WINPlatform.h +++ b/libraries/platform/src/WINPlatform.h @@ -18,7 +18,7 @@ namespace platform { void enumerateCpu() override; void enumerateMemory() override; void enumerateGpu() override; - + void enumerateComputer () override; }; } // namespace platform diff --git a/libraries/platform/src/platform.cpp b/libraries/platform/src/platform.cpp index 27e773d435..64bd536eee 100644 --- a/libraries/platform/src/platform.cpp +++ b/libraries/platform/src/platform.cpp @@ -77,3 +77,7 @@ int platform::getNumMemory() { json platform::getMemory(int index) { return _instance->getMemory(index); } + +json platform::getComputer(){ + return _instance->getComputer(); +} diff --git a/libraries/platform/src/platform.h b/libraries/platform/src/platform.h index 895114ba6d..14ec5fa8b2 100644 --- a/libraries/platform/src/platform.h +++ b/libraries/platform/src/platform.h @@ -9,8 +9,7 @@ #ifndef hifi_Platform_h #define hifi_Platform_h -#include "platformInstance.h" -#include + #include namespace platform { @@ -32,6 +31,8 @@ json getDisplay(int index); int getNumMemory(); json getMemory(int index); +json getComputer(); + } // namespace platform #endif // hifi_platform_h diff --git a/libraries/platform/src/platformInstance.cpp b/libraries/platform/src/platformInstance.cpp index 705f5bd358..5859577748 100644 --- a/libraries/platform/src/platformInstance.cpp +++ b/libraries/platform/src/platformInstance.cpp @@ -7,24 +7,13 @@ // -#include "platform.h" - +#include "platformInstance.h" #include -#ifdef Q_OS_WIN -#include "WINPlatform.h" -#endif - -#ifdef Q_OS_MACOS -#include "MACOSPlatform.h" -#endif - -#ifdef Q_OS_LINUX -#endif - using namespace platform; bool Instance::enumeratePlatform() { + enumerateComputer(); enumerateCpu(); enumerateGpu(); enumerateMemory(); @@ -75,7 +64,6 @@ Instance::~Instance() { _memory.clear(); } - if (_gpu.size() > 0) { _gpu.clear(); } diff --git a/libraries/platform/src/platformInstance.h b/libraries/platform/src/platformInstance.h index 4770200f07..8d0a181e3d 100644 --- a/libraries/platform/src/platformInstance.h +++ b/libraries/platform/src/platformInstance.h @@ -31,9 +31,13 @@ public: int getNumDisplay() { return (int)_display.size(); } json getDisplay(int index); + + json getComputer() {return _computer;} + void virtual enumerateCpu()=0; void virtual enumerateMemory()=0; void virtual enumerateGpu()=0; + void virtual enumerateComputer()=0; virtual ~Instance(); @@ -42,6 +46,7 @@ protected: std::vector _memory; std::vector _gpu; std::vector _display; + json _computer; }; } // namespace platform diff --git a/libraries/platform/src/platformJsonKeys.h b/libraries/platform/src/platformJsonKeys.h index 633add2b7e..31d81a829c 100644 --- a/libraries/platform/src/platformJsonKeys.h +++ b/libraries/platform/src/platformJsonKeys.h @@ -26,9 +26,12 @@ namespace platform { static const char* displayCoordsRight { "coordinatesright"}; static const char* displayCoordsTop { "coordinatestop"}; static const char* displayCoordsBottom { "coordinatesbottom"}; + static const char* computerModel { "computerModel"}; + #endif + } -} // namespace platform +} // namespace plaform::jsonKeys #endif diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index 7cb2f09bb7..735b1a48f6 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -91,7 +91,7 @@ void ProceduralData::parse(const QJsonObject& proceduralData) { } } - { // Fragment shader URL (either fragmentShaderUrl or shaderUrl) + { // Fragment shader URL (either fragmentShaderURL or shaderUrl) auto rawShaderUrl = proceduralData[FRAGMENT_URL_KEY].toString(); fragmentShaderUrl = DependencyManager::get()->normalizeURL(rawShaderUrl); diff --git a/libraries/procedural/src/procedural/Procedural.h b/libraries/procedural/src/procedural/Procedural.h index 1b190ec715..aac353bf7c 100644 --- a/libraries/procedural/src/procedural/Procedural.h +++ b/libraries/procedural/src/procedural/Procedural.h @@ -196,7 +196,6 @@ class ProceduralMaterial : public NetworkMaterial { public: ProceduralMaterial() : NetworkMaterial() { initializeProcedural(); } ProceduralMaterial(const NetworkMaterial& material) : NetworkMaterial(material) { initializeProcedural(); } - //ProceduralMaterial(const ProceduralMaterial& material) : NetworkMaterial(material), _procedural(material._procedural) {} bool isProcedural() const override { return true; } bool isEnabled() const override { return _procedural.isEnabled(); } diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index fac9082c74..7f42b05fa4 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -76,7 +76,6 @@ void CauterizedModel::createRenderItemSet() { // Run through all of the meshes, and place them into their segregated, but unsorted buckets int shapeID = 0; uint32_t numMeshes = (uint32_t)meshes.size(); - const HFMModel& hfmModel = getHFMModel(); for (uint32_t i = 0; i < numMeshes; i++) { const auto& mesh = meshes.at(i); if (!mesh) { @@ -86,8 +85,6 @@ void CauterizedModel::createRenderItemSet() { // Create the render payloads int numParts = (int)mesh->getNumParts(); for (int partIndex = 0; partIndex < numParts; partIndex++) { - initializeBlendshapes(hfmModel.meshes[i], i); - auto ptr = std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset, _created); _modelMeshRenderItems << std::static_pointer_cast(ptr); auto material = getGeometry()->getShapeMaterial(shapeID); @@ -96,7 +93,6 @@ void CauterizedModel::createRenderItemSet() { shapeID++; } } - _blendshapeOffsetsInitialized = true; } else { Model::createRenderItemSet(); } @@ -181,7 +177,7 @@ void CauterizedModel::updateClusterMatrices() { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index b22f738bd1..a4239ccda2 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -21,7 +21,7 @@ #include "RenderPipelines.h" -bool MeshPartPayload::enableMeshShaders = true; +bool MeshPartPayload::enableMeshShaders = false; using namespace render; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 5ea03c1583..e820637e0f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -315,10 +315,8 @@ bool Model::updateGeometry() { state.clusterDualQuaternions.resize(mesh.clusters.size()); state.clusterMatrices.resize(mesh.clusters.size()); _meshStates.push_back(state); - initializeBlendshapes(mesh, i); i++; } - _blendshapeOffsetsInitialized = true; needFullUpdate = true; emit rigReady(); } @@ -1023,9 +1021,6 @@ void Model::removeFromScene(const render::ScenePointer& scene, render::Transacti _modelMeshRenderItemShapes.clear(); _priorityMap.clear(); - _blendshapeOffsets.clear(); - _blendshapeOffsetsInitialized = false; - _addedToScene = false; _renderInfoVertexCount = 0; @@ -1416,7 +1411,7 @@ void Model::updateClusterMatrices() { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } @@ -1424,8 +1419,6 @@ void Model::updateClusterMatrices() { void Model::deleteGeometry() { _deleteGeometryCounter++; - _blendshapeOffsets.clear(); - _blendshapeOffsetsInitialized = false; _meshStates.clear(); _rig.destroyAnimGraph(); _blendedBlendshapeCoefficients.clear(); @@ -1485,7 +1478,6 @@ void Model::createRenderItemSet() { // Run through all of the meshes, and place them into their segregated, but unsorted buckets int shapeID = 0; uint32_t numMeshes = (uint32_t)meshes.size(); - auto& hfmModel = getHFMModel(); for (uint32_t i = 0; i < numMeshes; i++) { const auto& mesh = meshes.at(i); if (!mesh) { @@ -1495,7 +1487,6 @@ void Model::createRenderItemSet() { // Create the render payloads int numParts = (int)mesh->getNumParts(); for (int partIndex = 0; partIndex < numParts; partIndex++) { - initializeBlendshapes(hfmModel.meshes[i], i); _modelMeshRenderItems << std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset, _created); auto material = getGeometry()->getShapeMaterial(shapeID); _modelMeshMaterialNames.push_back(material ? material->getName() : ""); @@ -1503,7 +1494,6 @@ void Model::createRenderItemSet() { shapeID++; } } - _blendshapeOffsetsInitialized = true; } bool Model::isRenderable() const { @@ -1723,119 +1713,104 @@ void packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10(glm::uvec4& pac class Blender : public QRunnable { public: - Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointer& geometry, const QVector& blendshapeCoefficients); + Blender(ModelPointer model, HFMModel::ConstPointer hfmModel, int blendNumber, const QVector& blendshapeCoefficients); virtual void run() override; private: - ModelPointer _model; + HFMModel::ConstPointer _hfmModel; int _blendNumber; - Geometry::WeakPointer _geometry; QVector _blendshapeCoefficients; }; -Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointer& geometry, const QVector& blendshapeCoefficients) : +Blender::Blender(ModelPointer model, HFMModel::ConstPointer hfmModel, int blendNumber, const QVector& blendshapeCoefficients) : _model(model), + _hfmModel(hfmModel), _blendNumber(blendNumber), - _geometry(geometry), _blendshapeCoefficients(blendshapeCoefficients) { } void Blender::run() { - QVector blendshapeOffsets; + DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } }); + int numBlendshapeOffsets = 0; // number of offsets required for all meshes. + int numMeshes = 0; // number of meshes in this model. + for (auto meshIter = _hfmModel->meshes.cbegin(); meshIter != _hfmModel->meshes.cend(); ++meshIter) { + numMeshes++; + int numVertsInMesh = meshIter->vertices.size(); + numBlendshapeOffsets += numVertsInMesh; + } + + // all elements are default constructed to zero offsets. + QVector packedBlendshapeOffsets(numBlendshapeOffsets); + QVector unpackedBlendshapeOffsets(numBlendshapeOffsets); + + // allocate the required size QVector blendedMeshSizes; - if (_model && _model->isLoaded()) { - DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } }); - int offset = 0; - const auto& meshes = _model->getHFMModel().meshes; - int meshIndex = 0; - for(const HFMMesh& mesh : meshes) { - auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++); - if (mesh.blendshapes.isEmpty() || modelMeshBlendshapeOffsets == _model->_blendshapeOffsets.end()) { - // Not blendshaped or not initialized - blendedMeshSizes.push_back(0); + blendedMeshSizes.reserve(numMeshes); + + int offset = 0; + for (auto meshIter = _hfmModel->meshes.cbegin(); meshIter != _hfmModel->meshes.cend(); ++meshIter) { + if (meshIter->blendshapes.isEmpty()) { + blendedMeshSizes.push_back(0); + continue; + } + int numVertsInMesh = meshIter->vertices.size(); + blendedMeshSizes.push_back(numVertsInMesh); + + // for each blendshape in this mesh, accumulate the offsets into unpackedBlendshapeOffsets. + const float NORMAL_COEFFICIENT_SCALE = 0.01f; + for (int i = 0, n = qMin(_blendshapeCoefficients.size(), meshIter->blendshapes.size()); i < n; i++) { + float vertexCoefficient = _blendshapeCoefficients.at(i); + const float EPSILON = 0.0001f; + if (vertexCoefficient < EPSILON) { continue; } - if (mesh.vertices.size() != modelMeshBlendshapeOffsets->second.size()) { - // Mesh sizes don't match. Something has gone wrong - blendedMeshSizes.push_back(0); - continue; - } + float normalCoefficient = vertexCoefficient * NORMAL_COEFFICIENT_SCALE; + const HFMBlendshape& blendshape = meshIter->blendshapes.at(i); + for (int j = 0; j < blendshape.indices.size(); ++j) { + int index = blendshape.indices.at(j); - blendshapeOffsets += modelMeshBlendshapeOffsets->second; - BlendshapeOffset* meshBlendshapeOffsets = blendshapeOffsets.data() + offset; - int numVertices = modelMeshBlendshapeOffsets->second.size(); - blendedMeshSizes.push_back(numVertices); - offset += numVertices; - std::vector unpackedBlendshapeOffsets(modelMeshBlendshapeOffsets->second.size()); - - const float NORMAL_COEFFICIENT_SCALE = 0.01f; - for (int i = 0, n = qMin(_blendshapeCoefficients.size(), mesh.blendshapes.size()); i < n; i++) { - float vertexCoefficient = _blendshapeCoefficients.at(i); - const float EPSILON = 0.0001f; - if (vertexCoefficient < EPSILON) { - continue; - } - - float normalCoefficient = vertexCoefficient * NORMAL_COEFFICIENT_SCALE; - const HFMBlendshape& blendshape = mesh.blendshapes.at(i); - for (int j = 0; j < blendshape.indices.size(); ++j) { - int index = blendshape.indices.at(j); - - auto& currentBlendshapeOffset = unpackedBlendshapeOffsets[index]; - currentBlendshapeOffset.positionOffset += blendshape.vertices.at(j) * vertexCoefficient; - - currentBlendshapeOffset.normalOffset += blendshape.normals.at(j) * normalCoefficient; - if (j < blendshape.tangents.size()) { - currentBlendshapeOffset.tangentOffset += blendshape.tangents.at(j) * normalCoefficient; - } - } - } - - // Blendshape offsets are generrated, now let's pack it on its way to gpu - // FIXME it feels like we could be more effectively using SIMD here - { - auto unpacked = unpackedBlendshapeOffsets.data(); - auto packed = meshBlendshapeOffsets; - for (int j = 0; j < (int)unpackedBlendshapeOffsets.size(); ++j) { - packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10((*packed).packedPosNorTan, (*unpacked)); - ++unpacked; - ++packed; + auto& currentBlendshapeOffset = unpackedBlendshapeOffsets[offset + index]; + currentBlendshapeOffset.positionOffset += blendshape.vertices.at(j) * vertexCoefficient; + currentBlendshapeOffset.normalOffset += blendshape.normals.at(j) * normalCoefficient; + if (j < blendshape.tangents.size()) { + currentBlendshapeOffset.tangentOffset += blendshape.tangents.at(j) * normalCoefficient; } } } + offset += numVertsInMesh; } + + // convert unpackedBlendshapeOffsets into packedBlendshapeOffsets for the gpu. + // FIXME it feels like we could be more effectively using SIMD here + { + auto unpacked = unpackedBlendshapeOffsets.data(); + auto packed = packedBlendshapeOffsets.data(); + for (int i = 0; i < unpackedBlendshapeOffsets.size(); ++i) { + packBlendshapeOffsetTo_Pos_F32_3xSN10_Nor_3xSN10_Tan_3xSN10((*packed).packedPosNorTan, (*unpacked)); + ++unpacked; + ++packed; + } + } + // post the result to the ModelBlender, which will dispatch to the model if still alive QMetaObject::invokeMethod(DependencyManager::get().data(), "setBlendedVertices", - Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), Q_ARG(QVector, blendshapeOffsets), Q_ARG(QVector, blendedMeshSizes)); + Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), + Q_ARG(QVector, packedBlendshapeOffsets), + Q_ARG(QVector, blendedMeshSizes)); } bool Model::maybeStartBlender() { if (isLoaded()) { - QThreadPool::globalInstance()->start(new Blender(getThisPointer(), ++_blendNumber, _renderGeometry, _blendshapeCoefficients)); + QThreadPool::globalInstance()->start(new Blender(getThisPointer(), getGeometry()->getConstHFMModelPointer(), + ++_blendNumber, _blendshapeCoefficients)); return true; } return false; } -void Model::initializeBlendshapes(const HFMMesh& mesh, int index) { - if (mesh.blendshapes.empty()) { - // mesh doesn't have blendshape, did we allocate one though ? - if (_blendshapeOffsets.find(index) != _blendshapeOffsets.end()) { - qWarning() << "Mesh does not have Blendshape yet the blendshapeOffsets are allocated ?"; - } - return; - } - // Mesh has blendshape, let s allocate the local buffer if not done yet - if (_blendshapeOffsets.find(index) == _blendshapeOffsets.end()) { - QVector blendshapeOffset; - blendshapeOffset.fill(BlendshapeOffset(), mesh.vertices.size()); - _blendshapeOffsets[index] = blendshapeOffset; - } -} - ModelBlender::ModelBlender() : _pendingBlenders(0) { } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index da95fdef10..597fe552f7 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -363,8 +363,6 @@ public: void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName); void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName); - std::unordered_map> _blendshapeOffsets; - public slots: void loadURLFinished(bool success); @@ -446,7 +444,6 @@ protected: QVector _blendshapeCoefficients; QVector _blendedBlendshapeCoefficients; int _blendNumber { 0 }; - bool _blendshapeOffsetsInitialized { false }; mutable QMutex _mutex{ QMutex::Recursive }; @@ -509,8 +506,6 @@ protected: bool shouldInvalidatePayloadShapeKey(int meshIndex); - void initializeBlendshapes(const HFMMesh& mesh, int index); - uint64_t _created; private: diff --git a/libraries/render-utils/src/RenderViewTask.cpp b/libraries/render-utils/src/RenderViewTask.cpp index ffaecedb0b..93a3ff2d67 100644 --- a/libraries/render-utils/src/RenderViewTask.cpp +++ b/libraries/render-utils/src/RenderViewTask.cpp @@ -15,8 +15,6 @@ #include "RenderDeferredTask.h" #include "RenderForwardTask.h" -#include - void RenderShadowsAndDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) { task.addJob("SetRenderMethodTask", render::Args::DEFERRED); @@ -34,9 +32,9 @@ void RenderShadowsAndDeferredTask::build(JobModel& task, const render::Varying& } void DeferredForwardSwitchJob::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) { - task.addBranch("RenderShadowsAndDeferredTask", RENDER_FORWARD ? 1 : 0, input, cullFunctor, tagBits, tagMask); + task.addBranch("RenderShadowsAndDeferredTask", 0, input, cullFunctor, tagBits, tagMask); - task.addBranch("RenderForwardTask", RENDER_FORWARD ? 0 : 1, input); + task.addBranch("RenderForwardTask", 1, input); } void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) { diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index a6f82e1417..186f9e682a 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -71,7 +71,7 @@ void SoftAttachmentModel::updateClusterMatrices() { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } diff --git a/libraries/shared/src/GPUIdent.cpp b/libraries/shared/src/GPUIdent.cpp index a78ded483b..773e40aaee 100644 --- a/libraries/shared/src/GPUIdent.cpp +++ b/libraries/shared/src/GPUIdent.cpp @@ -22,6 +22,10 @@ #elif defined(Q_OS_MAC) #include +#include +#include +#include + #endif #include @@ -56,6 +60,27 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) } } } + + //get gpu name + FILE* stream = popen("system_profiler SPDisplaysDataType | grep Chipset", "r"); + + std::ostringstream hostStream; + while (!feof(stream) && !ferror(stream)) { + char buf[128]; + int bytesRead = fread(buf, 1, 128, stream); + hostStream.write(buf, bytesRead); + } + + QString result = QString::fromStdString(hostStream.str()); + QStringList parts = result.split('\n'); + std::string name; + + for (int i = 0; i < parts.size(); ++i) { + if (parts[i].toLower().contains("radeon") || parts[i].toLower().contains("nvidia")) { + _name=parts[i]; + } + } + _dedicatedMemoryMB = bestVRAM; CGLDestroyRendererInfo(rendererInfo); diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h index 891970006d..ab76bc5fba 100644 --- a/libraries/task/src/task/Config.h +++ b/libraries/task/src/task/Config.h @@ -220,7 +220,6 @@ public: TaskConfig() = default; TaskConfig(bool enabled) : JobConfig(enabled) {} - /**jsdoc * @function Render.getConfig * @param {string} name @@ -262,7 +261,7 @@ public: class SwitchConfig : public JobConfig { Q_OBJECT - Q_PROPERTY(bool branch READ getBranch WRITE setBranch NOTIFY dirtyEnabled) + Q_PROPERTY(int branch READ getBranch WRITE setBranch NOTIFY dirtyEnabled) public: uint8_t getBranch() const { return _branch; }