From 8e73fa3eb4a3855a3fe13319c5ba14ca46d0d299 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 21 Apr 2017 18:16:07 -0700 Subject: [PATCH] Separating the task classes in their own folder, and easing the declaration --- .../render-utils/src/DeferredLightingEffect.h | 1 - .../render-utils/src/RenderShadowTask.cpp | 1 - libraries/render/src/render/Context.h | 46 -- libraries/render/src/render/Engine.h | 61 +- .../src/render/RenderFetchCullSortTask.h | 2 - libraries/render/src/render/Task.h | 769 ------------------ .../src/{render/Task.cpp => task/Config.cpp} | 10 +- libraries/render/src/task/Config.h | 169 ++++ libraries/render/src/task/Task.h | 326 ++++++++ libraries/render/src/task/Varying.h | 287 +++++++ tests/gpu-test/src/TestWindow.h | 2 +- 11 files changed, 847 insertions(+), 827 deletions(-) delete mode 100644 libraries/render/src/render/Context.h delete mode 100644 libraries/render/src/render/Task.h rename libraries/render/src/{render/Task.cpp => task/Config.cpp} (95%) create mode 100644 libraries/render/src/task/Config.h create mode 100644 libraries/render/src/task/Task.h create mode 100644 libraries/render/src/task/Varying.h diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index c5e694cb18..dcf0c84622 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -20,7 +20,6 @@ #include "model/Light.h" #include "model/Geometry.h" -#include "render/Context.h" #include #include "DeferredFrameTransform.h" diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 0a4371cccd..d7ec087174 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -15,7 +15,6 @@ #include -#include #include #include #include diff --git a/libraries/render/src/render/Context.h b/libraries/render/src/render/Context.h deleted file mode 100644 index c493bda4b2..0000000000 --- a/libraries/render/src/render/Context.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// Context.h -// render/src/render -// -// Created by Zach Pomerantz on 1/6/2015. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_render_Context_h -#define hifi_render_Context_h - -#include "Scene.h" - - -namespace task { - -class JobConfig; - -class JobContext { -public: - virtual ~JobContext() {} - - std::shared_ptr jobConfig{ nullptr }; -}; -using JobContextPointer = std::shared_ptr; -} - -namespace render { - - -class RenderContext : public task::JobContext { -public: - virtual ~RenderContext() {} - - RenderArgs* args; - ScenePointer _scene; -}; -using RenderContextPointer = std::shared_ptr; - -} - -#endif // hifi_render_Context_h - diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 68d86e6c16..d4dba0e340 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -14,10 +14,67 @@ #include -#include "Context.h" -#include "Task.h" +#include "Scene.h" +#include "../task/Task.h" +#include "gpu/Batch.h" + namespace render { + + + class RenderContext : public task::JobContext { + public: + virtual ~RenderContext() {} + + RenderArgs* args; + ScenePointer _scene; + }; + using RenderContextPointer = std::shared_ptr; + + Task_DeclareTypeAliases(RenderContext) + + // Versions of the COnfig integrating a gpu & batch timer + class GPUJobConfig : public JobConfig { + Q_OBJECT + Q_PROPERTY(double gpuRunTime READ getGPURunTime) + Q_PROPERTY(double batchRunTime READ getBatchRunTime) + + double _msGPURunTime { 0.0 }; + double _msBatchRunTime { 0.0 }; + public: + using Persistent = PersistentConfig; + + GPUJobConfig() = default; + GPUJobConfig(bool enabled) : JobConfig(enabled) {} + + // Running Time measurement on GPU and for Batch execution + void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; } + double getGPURunTime() const { return _msGPURunTime; } + double getBatchRunTime() const { return _msBatchRunTime; } + }; + + class GPUTaskConfig : public TaskConfig { + Q_OBJECT + Q_PROPERTY(double gpuRunTime READ getGPURunTime) + Q_PROPERTY(double batchRunTime READ getBatchRunTime) + + double _msGPURunTime { 0.0 }; + double _msBatchRunTime { 0.0 }; + public: + + using Persistent = PersistentConfig; + + + GPUTaskConfig() = default; + GPUTaskConfig(bool enabled) : TaskConfig(enabled) {} + + // Running Time measurement on GPU and for Batch execution + void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; } + double getGPURunTime() const { return _msGPURunTime; } + double getBatchRunTime() const { return _msBatchRunTime; } + }; + + // The render engine holds all render tasks, and is itself a render task. // State flows through tasks to jobs via the render and scene contexts - // the engine should not be known from its jobs. diff --git a/libraries/render/src/render/RenderFetchCullSortTask.h b/libraries/render/src/render/RenderFetchCullSortTask.h index 12bcb9786d..f32293f001 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.h +++ b/libraries/render/src/render/RenderFetchCullSortTask.h @@ -13,8 +13,6 @@ #define hifi_RenderFetchCullSortTask_h #include - -#include "Task.h" #include "CullTask.h" class RenderFetchCullSortTask { diff --git a/libraries/render/src/render/Task.h b/libraries/render/src/render/Task.h deleted file mode 100644 index a4d60b25cc..0000000000 --- a/libraries/render/src/render/Task.h +++ /dev/null @@ -1,769 +0,0 @@ -// -// Task.h -// render/src/render -// -// Created by Zach Pomerantz on 1/6/2016. -// Copyright 2016 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_render_Task_h -#define hifi_render_Task_h -#include - -#include - -#include -#include -#include -#include - -#include "SettingHandle.h" - -#include "Context.h" -#include "Logging.h" - -#include "gpu/Batch.h" -#include - -namespace task { - -// A varying piece of data, to be used as Job/Task I/O -class Varying { -public: - Varying() {} - Varying(const Varying& var) : _concept(var._concept) {} - Varying& operator=(const Varying& var) { - _concept = var._concept; - return (*this); - } - template Varying(const T& data) : _concept(std::make_shared>(data)) {} - - template bool canCast() const { return !!std::dynamic_pointer_cast>(_concept); } - template const T& get() const { return std::static_pointer_cast>(_concept)->_data; } - template T& edit() { return std::static_pointer_cast>(_concept)->_data; } - - - // access potential sub varyings contained in this one. - Varying operator[] (uint8_t index) const { return (*_concept)[index]; } - uint8_t length() const { return (*_concept).length(); } - - template Varying getN (uint8_t index) const { return get()[index]; } - template Varying editN (uint8_t index) { return edit()[index]; } - -protected: - class Concept { - public: - virtual ~Concept() = default; - - virtual Varying operator[] (uint8_t index) const = 0; - virtual uint8_t length() const = 0; - }; - template class Model : public Concept { - public: - using Data = T; - - Model(const Data& data) : _data(data) {} - virtual ~Model() = default; - - virtual Varying operator[] (uint8_t index) const override { - Varying var; - return var; - } - virtual uint8_t length() const override { return 0; } - - Data _data; - }; - - std::shared_ptr _concept; -}; - -using VaryingPairBase = std::pair; -template < typename T0, typename T1 > -class VaryingSet2 : public VaryingPairBase { -public: - using Parent = VaryingPairBase; - typedef void is_proxy_tag; - - VaryingSet2() : Parent(Varying(T0()), Varying(T1())) {} - VaryingSet2(const VaryingSet2& pair) : Parent(pair.first, pair.second) {} - VaryingSet2(const Varying& first, const Varying& second) : Parent(first, second) {} - - const T0& get0() const { return first.get(); } - T0& edit0() { return first.edit(); } - - const T1& get1() const { return second.get(); } - T1& edit1() { return second.edit(); } - - virtual Varying operator[] (uint8_t index) const { - if (index == 1) { - return std::get<1>((*this)); - } else { - return std::get<0>((*this)); - } - } - virtual uint8_t length() const { return 2; } - - Varying hasVarying() const { return Varying((*this)); } -}; - - -template -class VaryingSet3 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet3() : Parent(Varying(T0()), Varying(T1()), Varying(T2())) {} - VaryingSet3(const VaryingSet3& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src)) {} - VaryingSet3(const Varying& first, const Varying& second, const Varying& third) : Parent(first, second, third) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - virtual Varying operator[] (uint8_t index) const { - if (index == 2) { - return std::get<2>((*this)); - } else if (index == 1) { - return std::get<1>((*this)); - } else { - return std::get<0>((*this)); - } - } - virtual uint8_t length() const { return 3; } - - Varying hasVarying() const { return Varying((*this)); } -}; - -template -class VaryingSet4 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet4() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3())) {} - VaryingSet4(const VaryingSet4& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src)) {} - VaryingSet4(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth) : Parent(first, second, third, fourth) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - const T3& get3() const { return std::get<3>((*this)).template get(); } - T3& edit3() { return std::get<3>((*this)).template edit(); } - - virtual Varying operator[] (uint8_t index) const { - if (index == 3) { - return std::get<3>((*this)); - } else if (index == 2) { - return std::get<2>((*this)); - } else if (index == 1) { - return std::get<1>((*this)); - } else { - return std::get<0>((*this)); - } - } - virtual uint8_t length() const { return 4; } - - Varying hasVarying() const { return Varying((*this)); } -}; - - -template -class VaryingSet5 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet5() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4())) {} - VaryingSet5(const VaryingSet5& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src)) {} - VaryingSet5(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth) : Parent(first, second, third, fourth, fifth) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - const T3& get3() const { return std::get<3>((*this)).template get(); } - T3& edit3() { return std::get<3>((*this)).template edit(); } - - const T4& get4() const { return std::get<4>((*this)).template get(); } - T4& edit4() { return std::get<4>((*this)).template edit(); } - - virtual Varying operator[] (uint8_t index) const { - if (index == 4) { - return std::get<4>((*this)); - } else if (index == 3) { - return std::get<3>((*this)); - } else if (index == 2) { - return std::get<2>((*this)); - } else if (index == 1) { - return std::get<1>((*this)); - } else { - return std::get<0>((*this)); - } - } - virtual uint8_t length() const { return 5; } - - Varying hasVarying() const { return Varying((*this)); } -}; - -template -class VaryingSet6 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet6() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5())) {} - VaryingSet6(const VaryingSet6& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src)) {} - VaryingSet6(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth) : Parent(first, second, third, fourth, fifth, sixth) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - const T3& get3() const { return std::get<3>((*this)).template get(); } - T3& edit3() { return std::get<3>((*this)).template edit(); } - - const T4& get4() const { return std::get<4>((*this)).template get(); } - T4& edit4() { return std::get<4>((*this)).template edit(); } - - const T5& get5() const { return std::get<5>((*this)).template get(); } - T5& edit5() { return std::get<5>((*this)).template edit(); } - - Varying hasVarying() const { return Varying((*this)); } -}; - -template -class VaryingSet7 : public std::tuple{ -public: - using Parent = std::tuple; - - VaryingSet7() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6())) {} - VaryingSet7(const VaryingSet7& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src)) {} - VaryingSet7(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh) : Parent(first, second, third, fourth, fifth, sixth, seventh) {} - - const T0& get0() const { return std::get<0>((*this)).template get(); } - T0& edit0() { return std::get<0>((*this)).template edit(); } - - const T1& get1() const { return std::get<1>((*this)).template get(); } - T1& edit1() { return std::get<1>((*this)).template edit(); } - - const T2& get2() const { return std::get<2>((*this)).template get(); } - T2& edit2() { return std::get<2>((*this)).template edit(); } - - const T3& get3() const { return std::get<3>((*this)).template get(); } - T3& edit3() { return std::get<3>((*this)).template edit(); } - - const T4& get4() const { return std::get<4>((*this)).template get(); } - T4& edit4() { return std::get<4>((*this)).template edit(); } - - const T5& get5() const { return std::get<5>((*this)).template get(); } - T5& edit5() { return std::get<5>((*this)).template edit(); } - - const T6& get6() const { return std::get<6>((*this)).template get(); } - T6& edit6() { return std::get<6>((*this)).template edit(); } - - Varying hasVarying() const { return Varying((*this)); } -}; - - -template < class T, int NUM > -class VaryingArray : public std::array { -public: - VaryingArray() { - for (size_t i = 0; i < NUM; i++) { - (*this)[i] = Varying(T()); - } - } -}; - -class JobConcept; -template class JobT; -template class TaskT; -class JobNoIO {}; - -template class PersistentConfig : public C { -public: - const QString DEFAULT = "Default"; - const QString NONE = "None"; - - PersistentConfig() = delete; - PersistentConfig(const QString& path) : - _preset(QStringList() << "Render" << "Engine" << path, DEFAULT) { } - PersistentConfig(const QStringList& path) : - _preset(QStringList() << "Render" << "Engine" << path, DEFAULT) { } - PersistentConfig(const QString& path, bool enabled) : C(enabled), - _preset(QStringList() << "Render" << "Engine" << path, enabled ? DEFAULT : NONE) { } - PersistentConfig(const QStringList& path, bool enabled) : C(enabled), - _preset(QStringList() << "Render" << "Engine" << path, enabled ? DEFAULT : NONE) { } - - QStringList getPresetList() { - if (_presets.empty()) { - setPresetList(QJsonObject()); - } - return _presets.keys(); - } - - virtual void setPresetList(const QJsonObject& list) override { - assert(_presets.empty()); - - _default = toJsonValue(*this).toObject().toVariantMap(); - - _presets.unite(list.toVariantMap()); - if (C::alwaysEnabled || C::enabled) { - _presets.insert(DEFAULT, _default); - } - if (!C::alwaysEnabled) { - _presets.insert(NONE, QVariantMap{{ "enabled", false }}); - } - - auto preset = _preset.get(); - if (preset != _preset.getDefault() && _presets.contains(preset)) { - // Load the persisted configuration - C::load(_presets[preset].toMap()); - } - } - - QString getPreset() { return _preset.get(); } - - void setPreset(const QString& preset) { - _preset.set(preset); - if (_presets.contains(preset)) { - // Always start back at default to remain deterministic - QVariantMap config = _default; - QVariantMap presetConfig = _presets[preset].toMap(); - for (auto it = presetConfig.cbegin(); it != presetConfig.cend(); it++) { - config.insert(it.key(), it.value()); - } - C::load(config); - } - } - -protected: - QVariantMap _default; - QVariantMap _presets; - Setting::Handle _preset; -}; - -// A default Config is always on; to create an enableable Config, use the ctor JobConfig(bool enabled) -class JobConfig : public QObject { - Q_OBJECT - Q_PROPERTY(double cpuRunTime READ getCPURunTime NOTIFY newStats()) //ms - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) - - double _msCPURunTime{ 0.0 }; -public: - using Persistent = PersistentConfig; - - JobConfig() = default; - JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {} - - bool isEnabled() { return alwaysEnabled || enabled; } - void setEnabled(bool enable) { enabled = alwaysEnabled || enable; } - - bool alwaysEnabled{ true }; - bool enabled{ true }; - - virtual void setPresetList(const QJsonObject& object) { - for (auto it = object.begin(); it != object.end(); it++) { - JobConfig* child = findChild(it.key(), Qt::FindDirectChildrenOnly); - if (child) { - child->setPresetList(it.value().toObject()); - } - } - } - - // This must be named toJSON to integrate with the global scripting JSON object - Q_INVOKABLE QString toJSON() { return QJsonDocument(toJsonValue(*this).toObject()).toJson(QJsonDocument::Compact); } - Q_INVOKABLE void load(const QVariantMap& map) { qObjectFromJsonValue(QJsonObject::fromVariantMap(map), *this); emit loaded(); } - - // Running Time measurement - // The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated - void setCPURunTime(double mstime) { _msCPURunTime = mstime; emit newStats(); } - double getCPURunTime() const { return _msCPURunTime; } - -public slots: - void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); } - -signals: - void loaded(); - void newStats(); -}; - -class TaskConfig : public JobConfig { - Q_OBJECT -public: - using QConfigPointer = std::shared_ptr; - - using Persistent = PersistentConfig; - - TaskConfig() = default ; - TaskConfig(bool enabled) : JobConfig(enabled) {} - - // getter for qml integration, prefer the templated getter - Q_INVOKABLE QObject* getConfig(const QString& name) { return QObject::findChild(name); } - // getter for cpp (strictly typed), prefer this getter - template typename T::Config* getConfig(std::string job = "") const { - QString name = job.empty() ? QString() : QString(job.c_str()); // an empty string is not a null string - return findChild(name); - } - - void connectChildConfig(QConfigPointer childConfig, const std::string& name); - void transferChildrenConfigs(QConfigPointer source); - - JobConcept* _task; - -public slots: - void refresh(); -}; - -template void jobConfigure(T& data, const C& configuration) { - data.configure(configuration); -} -template void jobConfigure(T&, const JobConfig&) { - // nop, as the default JobConfig was used, so the data does not need a configure method -} -template void jobConfigure(T&, const TaskConfig&) { - // nop, as the default TaskConfig was used, so the data does not need a configure method -} - -template void jobRun(T& data, const RC& renderContext, const JobNoIO& input, JobNoIO& output) { - data.run(renderContext); -} -template void jobRun(T& data, const RC& renderContext, const I& input, JobNoIO& output) { - data.run(renderContext, input); -} -template void jobRun(T& data, const RC& renderContext, const JobNoIO& input, O& output) { - data.run(renderContext, output); -} -template void jobRun(T& data, const RC& renderContext, const I& input, O& output) { - data.run(renderContext, input, output); -} - -// The guts of a job -class JobConcept { -public: - using Config = JobConfig; - using QConfigPointer = std::shared_ptr; - - JobConcept(QConfigPointer config) : _config(config) {} - virtual ~JobConcept() = default; - - virtual const Varying getInput() const { return Varying(); } - virtual const Varying getOutput() const { return Varying(); } - - virtual QConfigPointer& getConfiguration() { return _config; } - virtual void applyConfiguration() = 0; - - void setCPURunTime(double mstime) { std::static_pointer_cast(_config)->setCPURunTime(mstime); } - - QConfigPointer _config; -protected: -}; - -template -class Job { -public: - using Context = RC; - using ContextPointer = std::shared_ptr; - using Config = JobConfig; - using QConfigPointer = std::shared_ptr; - using None = JobNoIO; - - //template - class Concept : public JobConcept { - public: - Concept(QConfigPointer config) : JobConcept(config) {} - virtual ~Concept() = default; - - virtual void run(const ContextPointer& renderContext) = 0; - }; - using ConceptPointer = std::shared_ptr; - - template class Model : public Concept { - public: - using Data = T; - using Input = I; - using Output = O; - - Data _data; - Varying _input; - Varying _output; - - const Varying getInput() const override { return _input; } - const Varying getOutput() const override { return _output; } - - template - Model(const Varying& input, QConfigPointer config, A&&... args) : - Concept(config), - _data(Data(std::forward(args)...)), - _input(input), - _output(Output()) { - applyConfiguration(); - } - - template - static std::shared_ptr create(const Varying& input, A&&... args) { - return std::make_shared(input, std::make_shared(), std::forward(args)...); - } - - - void applyConfiguration() override { - jobConfigure(_data, *std::static_pointer_cast(_config)); - } - - void run(const ContextPointer& renderContext) override { - renderContext->jobConfig = std::static_pointer_cast(_config); - if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->isEnabled()) { - jobRun(_data, renderContext, _input.get(), _output.edit()); - } - renderContext->jobConfig.reset(); - } - }; - template using ModelI = Model; - template using ModelO = Model; - template using ModelIO = Model; - - Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {} - - const Varying getInput() const { return _concept->getInput(); } - const Varying getOutput() const { return _concept->getOutput(); } - QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); } - void applyConfiguration() { return _concept->applyConfiguration(); } - - template T& edit() { - auto concept = std::static_pointer_cast(_concept); - assert(concept); - return concept->_data; - } - - virtual void run(const ContextPointer& renderContext) { - PerformanceTimer perfTimer(_name.c_str()); - PROFILE_RANGE(render, _name.c_str()); - auto start = usecTimestampNow(); - - _concept->run(renderContext); - - _concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0); - } - -protected: - ConceptPointer _concept; - std::string _name = ""; -}; - -// A task is a specialized job to run a collection of other jobs -// It can be created on any type T by aliasing the type JobModel in the class T -// using JobModel = Task::Model -// The class T is expected to have a "build" method acting as a constructor. -// The build method is where child Jobs can be added internally to the task -// where the input of the task can be setup to feed the child jobs -// and where the output of the task is defined -template -class Task : public Job { -public: - using Context = RC; - using ContextPointer = std::shared_ptr; - using Config = TaskConfig; - using _Job = Job; - using QConfigPointer = _Job::QConfigPointer; - using None = _Job::None; - using Concept = _Job::Concept; - using Jobs = std::vector<_Job>; - - Task(std::string name, ConceptPointer concept) : Job(name, concept) {} - - class TaskConcept : public Concept { - public: - Varying _input; - Varying _output; - Jobs _jobs; - - const Varying getInput() const override { return _input; } - const Varying getOutput() const override { return _output; } - - TaskConcept(const Varying& input, QConfigPointer config) : Concept(config), _input(input) {} - - // Create a new job in the container's queue; returns the job's output - template const Varying addJob(std::string name, const Varying& input, NA&&... args) { - _jobs.emplace_back(name, (NT::JobModel::create(input, std::forward(args)...))); - - // Conect the child config to this task's config - std::static_pointer_cast(getConfiguration())->connectChildConfig(_jobs.back().getConfiguration(), name); - - return _jobs.back().getOutput(); - } - template const Varying addJob(std::string name, NA&&... args) { - const auto input = Varying(typename NT::JobModel::Input()); - return addJob(name, input, std::forward(args)...); - } - }; - - template class TaskModel : public TaskConcept { - public: - using Data = T; - using Input = I; - using Output = O; - - Data _data; - - TaskModel(const Varying& input, QConfigPointer config) : - TaskConcept(input, config), - _data(Data()) {} - - template - static std::shared_ptr create(const Varying& input, A&&... args) { - auto model = std::make_shared(input, std::make_shared()); - - model->_data.build(*(model), model->_input, model->_output, std::forward(args)...); - - // Recreate the Config to use the templated type - model->createConfiguration(); - model->applyConfiguration(); - - return model; - } - - template - static std::shared_ptr create(A&&... args) { - const auto input = Varying(Input()); - return create(input, std::forward(args)...); - } - - void createConfiguration() { - // A brand new config - auto config = std::make_shared(); - // Make sure we transfer the former children configs to the new config - config->transferChildrenConfigs(_config); - // swap - _config = config; - // Capture this - std::static_pointer_cast(_config)->_task = this; - } - - QConfigPointer& getConfiguration() override { - if (!_config) { - createConfiguration(); - } - return _config; - } - - void applyConfiguration() override { - jobConfigure(_data, *std::static_pointer_cast(_config)); - for (auto& job : _jobs) { - job.applyConfiguration(); - } - } - - void run(const ContextPointer& renderContext) override { - auto config = std::static_pointer_cast(_config); - if (config->alwaysEnabled || config->enabled) { - for (auto job : _jobs) { - job.run(renderContext); - } - } - } - }; - template using Model = TaskModel; - template using ModelI = TaskModel; - template using ModelO = TaskModel; - template using ModelIO = TaskModel; - - // Create a new job in the Task's queue; returns the job's output - template const Varying addJob(std::string name, const Varying& input, A&&... args) { - return std::static_pointer_cast( _concept)->addJob(name, input, std::forward(args)...); - } - template const Varying addJob(std::string name, A&&... args) { - const auto input = Varying(typename T::JobModel::Input()); - return std::static_pointer_cast( _concept)->addJob(name, input, std::forward(args)...); - } - - std::shared_ptr getConfiguration() { - return std::static_pointer_cast(_concept->getConfiguration()); - } - -protected: -}; -} - -namespace render { -using JobConfig =task::JobConfig; -using TaskConfig =task::TaskConfig; - -template using PersistentConfig = task::PersistentConfig; - -using Job = task::Job; -using Task = task::Task; - -using Varying = task::Varying; -template < typename T0, typename T1 > using VaryingSet2 = task::VaryingSet2; -template < typename T0, typename T1, typename T2 > using VaryingSet3 = task::VaryingSet3; -template < typename T0, typename T1, typename T2, typename T3 > using VaryingSet4 = task::VaryingSet4; -template < typename T0, typename T1, typename T2, typename T3, typename T4 > using VaryingSet5 = task::VaryingSet5; -template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5 > using VaryingSet6 = task::VaryingSet6; -template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > using VaryingSet7 = task::VaryingSet7; -template < class T, int NUM > using VaryingArray = task::VaryingArray; - -// Versions of the COnfig integrating a gpu & batch timer -class GPUJobConfig : public JobConfig { - Q_OBJECT - Q_PROPERTY(double gpuRunTime READ getGPURunTime) - Q_PROPERTY(double batchRunTime READ getBatchRunTime) - - double _msGPURunTime { 0.0 }; - double _msBatchRunTime { 0.0 }; -public: - using Persistent = PersistentConfig; - - GPUJobConfig() = default; - GPUJobConfig(bool enabled) : JobConfig(enabled) {} - - // Running Time measurement on GPU and for Batch execution - void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; } - double getGPURunTime() const { return _msGPURunTime; } - double getBatchRunTime() const { return _msBatchRunTime; } -}; - -class GPUTaskConfig : public TaskConfig { - Q_OBJECT - Q_PROPERTY(double gpuRunTime READ getGPURunTime) - Q_PROPERTY(double batchRunTime READ getBatchRunTime) - - double _msGPURunTime { 0.0 }; - double _msBatchRunTime { 0.0 }; -public: - - using Persistent = PersistentConfig; - - - GPUTaskConfig() = default; - GPUTaskConfig(bool enabled) : TaskConfig(enabled) {} - - // Running Time measurement on GPU and for Batch execution - void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; } - double getGPURunTime() const { return _msGPURunTime; } - double getBatchRunTime() const { return _msBatchRunTime; } -}; - -} - -#endif // hifi_render_Task_h diff --git a/libraries/render/src/render/Task.cpp b/libraries/render/src/task/Config.cpp similarity index 95% rename from libraries/render/src/render/Task.cpp rename to libraries/render/src/task/Config.cpp index 13476f102e..587c4319af 100644 --- a/libraries/render/src/render/Task.cpp +++ b/libraries/render/src/task/Config.cpp @@ -1,6 +1,6 @@ // -// Task.cpp -// render/src/render +// Config.cpp +// render/src/task // // Created by Zach Pomerantz on 1/21/2016. // Copyright 2016 High Fidelity, Inc. @@ -8,12 +8,12 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -#include +#include "Config.h" #include "Task.h" +#include -using namespace render; +using namespace task; void TaskConfig::connectChildConfig(QConfigPointer childConfig, const std::string& name) { childConfig->setParent(this); diff --git a/libraries/render/src/task/Config.h b/libraries/render/src/task/Config.h new file mode 100644 index 0000000000..9e6f060d9d --- /dev/null +++ b/libraries/render/src/task/Config.h @@ -0,0 +1,169 @@ +// +// Config.h +// render/src/render +// +// Created by Zach Pomerantz on 1/6/2016. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_task_Config_h +#define hifi_task_Config_h + +#include +#include +#include +#include +#include + +#include "SettingHandle.h" + +#include "Logging.h" + +#include +#include + +namespace task { + +class JobConcept; + +template class PersistentConfig : public C { +public: + const QString DEFAULT = "Default"; + const QString NONE = "None"; + + PersistentConfig() = delete; + PersistentConfig(const QString& path) : + _preset(QStringList() << "Render" << "Engine" << path, DEFAULT) { } + PersistentConfig(const QStringList& path) : + _preset(QStringList() << "Render" << "Engine" << path, DEFAULT) { } + PersistentConfig(const QString& path, bool enabled) : C(enabled), + _preset(QStringList() << "Render" << "Engine" << path, enabled ? DEFAULT : NONE) { } + PersistentConfig(const QStringList& path, bool enabled) : C(enabled), + _preset(QStringList() << "Render" << "Engine" << path, enabled ? DEFAULT : NONE) { } + + QStringList getPresetList() { + if (_presets.empty()) { + setPresetList(QJsonObject()); + } + return _presets.keys(); + } + + virtual void setPresetList(const QJsonObject& list) override { + assert(_presets.empty()); + + _default = toJsonValue(*this).toObject().toVariantMap(); + + _presets.unite(list.toVariantMap()); + if (C::alwaysEnabled || C::enabled) { + _presets.insert(DEFAULT, _default); + } + if (!C::alwaysEnabled) { + _presets.insert(NONE, QVariantMap{{ "enabled", false }}); + } + + auto preset = _preset.get(); + if (preset != _preset.getDefault() && _presets.contains(preset)) { + // Load the persisted configuration + C::load(_presets[preset].toMap()); + } + } + + QString getPreset() { return _preset.get(); } + + void setPreset(const QString& preset) { + _preset.set(preset); + if (_presets.contains(preset)) { + // Always start back at default to remain deterministic + QVariantMap config = _default; + QVariantMap presetConfig = _presets[preset].toMap(); + for (auto it = presetConfig.cbegin(); it != presetConfig.cend(); it++) { + config.insert(it.key(), it.value()); + } + C::load(config); + } + } + +protected: + QVariantMap _default; + QVariantMap _presets; + Setting::Handle _preset; +}; + +// A default Config is always on; to create an enableable Config, use the ctor JobConfig(bool enabled) +class JobConfig : public QObject { + Q_OBJECT + Q_PROPERTY(double cpuRunTime READ getCPURunTime NOTIFY newStats()) //ms + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + + double _msCPURunTime{ 0.0 }; +public: + using Persistent = PersistentConfig; + + JobConfig() = default; + JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {} + + bool isEnabled() { return alwaysEnabled || enabled; } + void setEnabled(bool enable) { enabled = alwaysEnabled || enable; } + + bool alwaysEnabled{ true }; + bool enabled{ true }; + + virtual void setPresetList(const QJsonObject& object) { + for (auto it = object.begin(); it != object.end(); it++) { + JobConfig* child = findChild(it.key(), Qt::FindDirectChildrenOnly); + if (child) { + child->setPresetList(it.value().toObject()); + } + } + } + + // This must be named toJSON to integrate with the global scripting JSON object + Q_INVOKABLE QString toJSON() { return QJsonDocument(toJsonValue(*this).toObject()).toJson(QJsonDocument::Compact); } + Q_INVOKABLE void load(const QVariantMap& map) { qObjectFromJsonValue(QJsonObject::fromVariantMap(map), *this); emit loaded(); } + + // Running Time measurement + // The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated + void setCPURunTime(double mstime) { _msCPURunTime = mstime; emit newStats(); } + double getCPURunTime() const { return _msCPURunTime; } + +public slots: + void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); } + +signals: + void loaded(); + void newStats(); +}; + +class TaskConfig : public JobConfig { + Q_OBJECT +public: + using QConfigPointer = std::shared_ptr; + + using Persistent = PersistentConfig; + + TaskConfig() = default ; + TaskConfig(bool enabled) : JobConfig(enabled) {} + + // getter for qml integration, prefer the templated getter + Q_INVOKABLE QObject* getConfig(const QString& name) { return QObject::findChild(name); } + // getter for cpp (strictly typed), prefer this getter + template typename T::Config* getConfig(std::string job = "") const { + QString name = job.empty() ? QString() : QString(job.c_str()); // an empty string is not a null string + return findChild(name); + } + + void connectChildConfig(QConfigPointer childConfig, const std::string& name); + void transferChildrenConfigs(QConfigPointer source); + + JobConcept* _task; + +public slots: + void refresh(); +}; + +} + +#endif // hifi_task_Config_h diff --git a/libraries/render/src/task/Task.h b/libraries/render/src/task/Task.h new file mode 100644 index 0000000000..3fcea66786 --- /dev/null +++ b/libraries/render/src/task/Task.h @@ -0,0 +1,326 @@ +// +// Task.h +// render/src/task +// +// Created by Zach Pomerantz on 1/6/2016. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_task_Task_h +#define hifi_task_Task_h + +#include "Config.h" +#include "Varying.h" + +#include "SettingHandle.h" + +#include "Logging.h" + +#include +#include + +namespace task { + +class JobConcept; +template class JobT; +template class TaskT; +class JobNoIO {}; + +class JobContext { +public: + virtual ~JobContext() {} + + std::shared_ptr jobConfig { nullptr }; +}; +using JobContextPointer = std::shared_ptr; + +// The guts of a job +class JobConcept { +public: + using Config = JobConfig; + using QConfigPointer = std::shared_ptr; + + JobConcept(QConfigPointer config) : _config(config) {} + virtual ~JobConcept() = default; + + virtual const Varying getInput() const { return Varying(); } + virtual const Varying getOutput() const { return Varying(); } + + virtual QConfigPointer& getConfiguration() { return _config; } + virtual void applyConfiguration() = 0; + + void setCPURunTime(double mstime) { std::static_pointer_cast(_config)->setCPURunTime(mstime); } + + QConfigPointer _config; +protected: +}; + + +template void jobConfigure(T& data, const C& configuration) { + data.configure(configuration); +} +template void jobConfigure(T&, const JobConfig&) { + // nop, as the default JobConfig was used, so the data does not need a configure method +} +template void jobConfigure(T&, const TaskConfig&) { + // nop, as the default TaskConfig was used, so the data does not need a configure method +} + +template void jobRun(T& data, const RC& renderContext, const JobNoIO& input, JobNoIO& output) { + data.run(renderContext); +} +template void jobRun(T& data, const RC& renderContext, const I& input, JobNoIO& output) { + data.run(renderContext, input); +} +template void jobRun(T& data, const RC& renderContext, const JobNoIO& input, O& output) { + data.run(renderContext, output); +} +template void jobRun(T& data, const RC& renderContext, const I& input, O& output) { + data.run(renderContext, input, output); +} + +template +class Job { +public: + using Context = RC; + using ContextPointer = std::shared_ptr; + using Config = JobConfig; + using QConfigPointer = std::shared_ptr; + using None = JobNoIO; + + //template + class Concept : public JobConcept { + public: + Concept(QConfigPointer config) : JobConcept(config) {} + virtual ~Concept() = default; + + virtual void run(const ContextPointer& renderContext) = 0; + }; + using ConceptPointer = std::shared_ptr; + + template class Model : public Concept { + public: + using Data = T; + using Input = I; + using Output = O; + + Data _data; + Varying _input; + Varying _output; + + const Varying getInput() const override { return _input; } + const Varying getOutput() const override { return _output; } + + template + Model(const Varying& input, QConfigPointer config, A&&... args) : + Concept(config), + _data(Data(std::forward(args)...)), + _input(input), + _output(Output()) { + applyConfiguration(); + } + + template + static std::shared_ptr create(const Varying& input, A&&... args) { + return std::make_shared(input, std::make_shared(), std::forward(args)...); + } + + + void applyConfiguration() override { + jobConfigure(_data, *std::static_pointer_cast(_config)); + } + + void run(const ContextPointer& renderContext) override { + renderContext->jobConfig = std::static_pointer_cast(_config); + if (renderContext->jobConfig->alwaysEnabled || renderContext->jobConfig->isEnabled()) { + jobRun(_data, renderContext, _input.get(), _output.edit()); + } + renderContext->jobConfig.reset(); + } + }; + template using ModelI = Model; + template using ModelO = Model; + template using ModelIO = Model; + + Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {} + + const Varying getInput() const { return _concept->getInput(); } + const Varying getOutput() const { return _concept->getOutput(); } + QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); } + void applyConfiguration() { return _concept->applyConfiguration(); } + + template T& edit() { + auto concept = std::static_pointer_cast(_concept); + assert(concept); + return concept->_data; + } + + virtual void run(const ContextPointer& renderContext) { + PerformanceTimer perfTimer(_name.c_str()); + PROFILE_RANGE(render, _name.c_str()); + auto start = usecTimestampNow(); + + _concept->run(renderContext); + + _concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0); + } + +protected: + ConceptPointer _concept; + std::string _name = ""; +}; + +// A task is a specialized job to run a collection of other jobs +// It can be created on any type T by aliasing the type JobModel in the class T +// using JobModel = Task::Model +// The class T is expected to have a "build" method acting as a constructor. +// The build method is where child Jobs can be added internally to the task +// where the input of the task can be setup to feed the child jobs +// and where the output of the task is defined +template +class Task : public Job { +public: + using Context = RC; + using ContextPointer = std::shared_ptr; + using Config = TaskConfig; + using _Job = Job; + using QConfigPointer = _Job::QConfigPointer; + using None = _Job::None; + using Concept = _Job::Concept; + using Jobs = std::vector<_Job>; + + Task(std::string name, ConceptPointer concept) : Job(name, concept) {} + + class TaskConcept : public Concept { + public: + Varying _input; + Varying _output; + Jobs _jobs; + + const Varying getInput() const override { return _input; } + const Varying getOutput() const override { return _output; } + + TaskConcept(const Varying& input, QConfigPointer config) : Concept(config), _input(input) {} + + // Create a new job in the container's queue; returns the job's output + template const Varying addJob(std::string name, const Varying& input, NA&&... args) { + _jobs.emplace_back(name, (NT::JobModel::create(input, std::forward(args)...))); + + // Conect the child config to this task's config + std::static_pointer_cast(getConfiguration())->connectChildConfig(_jobs.back().getConfiguration(), name); + + return _jobs.back().getOutput(); + } + template const Varying addJob(std::string name, NA&&... args) { + const auto input = Varying(typename NT::JobModel::Input()); + return addJob(name, input, std::forward(args)...); + } + }; + + template class TaskModel : public TaskConcept { + public: + using Data = T; + using Input = I; + using Output = O; + + Data _data; + + TaskModel(const Varying& input, QConfigPointer config) : + TaskConcept(input, config), + _data(Data()) {} + + template + static std::shared_ptr create(const Varying& input, A&&... args) { + auto model = std::make_shared(input, std::make_shared()); + + model->_data.build(*(model), model->_input, model->_output, std::forward(args)...); + + // Recreate the Config to use the templated type + model->createConfiguration(); + model->applyConfiguration(); + + return model; + } + + template + static std::shared_ptr create(A&&... args) { + const auto input = Varying(Input()); + return create(input, std::forward(args)...); + } + + void createConfiguration() { + // A brand new config + auto config = std::make_shared(); + // Make sure we transfer the former children configs to the new config + config->transferChildrenConfigs(_config); + // swap + _config = config; + // Capture this + std::static_pointer_cast(_config)->_task = this; + } + + QConfigPointer& getConfiguration() override { + if (!_config) { + createConfiguration(); + } + return _config; + } + + void applyConfiguration() override { + jobConfigure(_data, *std::static_pointer_cast(_config)); + for (auto& job : _jobs) { + job.applyConfiguration(); + } + } + + void run(const ContextPointer& renderContext) override { + auto config = std::static_pointer_cast(_config); + if (config->alwaysEnabled || config->enabled) { + for (auto job : _jobs) { + job.run(renderContext); + } + } + } + }; + template using Model = TaskModel; + template using ModelI = TaskModel; + template using ModelO = TaskModel; + template using ModelIO = TaskModel; + + // Create a new job in the Task's queue; returns the job's output + template const Varying addJob(std::string name, const Varying& input, A&&... args) { + return std::static_pointer_cast( _concept)->addJob(name, input, std::forward(args)...); + } + template const Varying addJob(std::string name, A&&... args) { + const auto input = Varying(typename T::JobModel::Input()); + return std::static_pointer_cast( _concept)->addJob(name, input, std::forward(args)...); + } + + std::shared_ptr getConfiguration() { + return std::static_pointer_cast(_concept->getConfiguration()); + } + +protected: +}; +} + + +#define Task_DeclareTypeAliases(ContextName) \ + using JobConfig = task::JobConfig; \ + using TaskConfig = task::TaskConfig; \ + template using PersistentConfig = task::PersistentConfig; \ + using Job = task::Job<##ContextName>; \ + using Task = task::Task<##ContextName>; \ + using Varying = task::Varying; \ + template < typename T0, typename T1 > using VaryingSet2 = task::VaryingSet2; \ + template < typename T0, typename T1, typename T2 > using VaryingSet3 = task::VaryingSet3; \ + template < typename T0, typename T1, typename T2, typename T3 > using VaryingSet4 = task::VaryingSet4; \ + template < typename T0, typename T1, typename T2, typename T3, typename T4 > using VaryingSet5 = task::VaryingSet5; \ + template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5 > using VaryingSet6 = task::VaryingSet6; \ + template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > using VaryingSet7 = task::VaryingSet7; \ + template < class T, int NUM > using VaryingArray = task::VaryingArray; + +#endif // hifi_task_Task_h diff --git a/libraries/render/src/task/Varying.h b/libraries/render/src/task/Varying.h new file mode 100644 index 0000000000..50f4acd414 --- /dev/null +++ b/libraries/render/src/task/Varying.h @@ -0,0 +1,287 @@ +// +// Varying.h +// render/src/task +// +// Created by Zach Pomerantz on 1/6/2016. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_task_Varying_h +#define hifi_task_Varying_h + +#include +#include + +namespace task { + +// A varying piece of data, to be used as Job/Task I/O +class Varying { +public: + Varying() {} + Varying(const Varying& var) : _concept(var._concept) {} + Varying& operator=(const Varying& var) { + _concept = var._concept; + return (*this); + } + template Varying(const T& data) : _concept(std::make_shared>(data)) {} + + template bool canCast() const { return !!std::dynamic_pointer_cast>(_concept); } + template const T& get() const { return std::static_pointer_cast>(_concept)->_data; } + template T& edit() { return std::static_pointer_cast>(_concept)->_data; } + + + // access potential sub varyings contained in this one. + Varying operator[] (uint8_t index) const { return (*_concept)[index]; } + uint8_t length() const { return (*_concept).length(); } + + template Varying getN (uint8_t index) const { return get()[index]; } + template Varying editN (uint8_t index) { return edit()[index]; } + +protected: + class Concept { + public: + virtual ~Concept() = default; + + virtual Varying operator[] (uint8_t index) const = 0; + virtual uint8_t length() const = 0; + }; + template class Model : public Concept { + public: + using Data = T; + + Model(const Data& data) : _data(data) {} + virtual ~Model() = default; + + virtual Varying operator[] (uint8_t index) const override { + Varying var; + return var; + } + virtual uint8_t length() const override { return 0; } + + Data _data; + }; + + std::shared_ptr _concept; +}; + +using VaryingPairBase = std::pair; +template < typename T0, typename T1 > +class VaryingSet2 : public VaryingPairBase { +public: + using Parent = VaryingPairBase; + typedef void is_proxy_tag; + + VaryingSet2() : Parent(Varying(T0()), Varying(T1())) {} + VaryingSet2(const VaryingSet2& pair) : Parent(pair.first, pair.second) {} + VaryingSet2(const Varying& first, const Varying& second) : Parent(first, second) {} + + const T0& get0() const { return first.get(); } + T0& edit0() { return first.edit(); } + + const T1& get1() const { return second.get(); } + T1& edit1() { return second.edit(); } + + virtual Varying operator[] (uint8_t index) const { + if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 2; } + + Varying hasVarying() const { return Varying((*this)); } +}; + + +template +class VaryingSet3 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet3() : Parent(Varying(T0()), Varying(T1()), Varying(T2())) {} + VaryingSet3(const VaryingSet3& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src)) {} + VaryingSet3(const Varying& first, const Varying& second, const Varying& third) : Parent(first, second, third) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + virtual Varying operator[] (uint8_t index) const { + if (index == 2) { + return std::get<2>((*this)); + } else if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 3; } + + Varying hasVarying() const { return Varying((*this)); } +}; + +template +class VaryingSet4 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet4() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3())) {} + VaryingSet4(const VaryingSet4& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src)) {} + VaryingSet4(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth) : Parent(first, second, third, fourth) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + virtual Varying operator[] (uint8_t index) const { + if (index == 3) { + return std::get<3>((*this)); + } else if (index == 2) { + return std::get<2>((*this)); + } else if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 4; } + + Varying hasVarying() const { return Varying((*this)); } +}; + + +template +class VaryingSet5 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet5() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4())) {} + VaryingSet5(const VaryingSet5& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src)) {} + VaryingSet5(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth) : Parent(first, second, third, fourth, fifth) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + const T4& get4() const { return std::get<4>((*this)).template get(); } + T4& edit4() { return std::get<4>((*this)).template edit(); } + + virtual Varying operator[] (uint8_t index) const { + if (index == 4) { + return std::get<4>((*this)); + } else if (index == 3) { + return std::get<3>((*this)); + } else if (index == 2) { + return std::get<2>((*this)); + } else if (index == 1) { + return std::get<1>((*this)); + } else { + return std::get<0>((*this)); + } + } + virtual uint8_t length() const { return 5; } + + Varying hasVarying() const { return Varying((*this)); } +}; + +template +class VaryingSet6 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet6() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5())) {} + VaryingSet6(const VaryingSet6& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src)) {} + VaryingSet6(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth) : Parent(first, second, third, fourth, fifth, sixth) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + const T4& get4() const { return std::get<4>((*this)).template get(); } + T4& edit4() { return std::get<4>((*this)).template edit(); } + + const T5& get5() const { return std::get<5>((*this)).template get(); } + T5& edit5() { return std::get<5>((*this)).template edit(); } + + Varying hasVarying() const { return Varying((*this)); } +}; + +template +class VaryingSet7 : public std::tuple{ +public: + using Parent = std::tuple; + + VaryingSet7() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6())) {} + VaryingSet7(const VaryingSet7& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src)) {} + VaryingSet7(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh) : Parent(first, second, third, fourth, fifth, sixth, seventh) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + const T4& get4() const { return std::get<4>((*this)).template get(); } + T4& edit4() { return std::get<4>((*this)).template edit(); } + + const T5& get5() const { return std::get<5>((*this)).template get(); } + T5& edit5() { return std::get<5>((*this)).template edit(); } + + const T6& get6() const { return std::get<6>((*this)).template get(); } + T6& edit6() { return std::get<6>((*this)).template edit(); } + + Varying hasVarying() const { return Varying((*this)); } +}; + + +template < class T, int NUM > +class VaryingArray : public std::array { +public: + VaryingArray() { + for (size_t i = 0; i < NUM; i++) { + (*this)[i] = Varying(T()); + } + } +}; +} + +#endif // hifi_task_Varying_h diff --git a/tests/gpu-test/src/TestWindow.h b/tests/gpu-test/src/TestWindow.h index fd059f3e32..bceb29305e 100644 --- a/tests/gpu-test/src/TestWindow.h +++ b/tests/gpu-test/src/TestWindow.h @@ -17,7 +17,7 @@ #include #include -#include +#include #define DEFERRED_LIGHTING