Refine Configuration for render::Job

wip

wip

wip

wip
This commit is contained in:
Zach Pomerantz 2016-01-21 11:44:22 -08:00
parent 581003ec83
commit 2e1fbf66ad
12 changed files with 161 additions and 109 deletions

View file

@ -1251,6 +1251,7 @@ void Application::initializeUi() {
rootContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
rootContext->setContextProperty("Scene", DependencyManager::get<SceneScriptingInterface>().data());
rootContext->setContextProperty("Render", DependencyManager::get<RenderScriptingInterface>().data());
// TODO: Expose Engine here
_glWidget->installEventFilter(offscreenUi.data());
offscreenUi->setMouseTranslator([=](const QPointF& pt) {
@ -4200,6 +4201,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
scriptEngine->registerGlobalObject("Scene", DependencyManager::get<SceneScriptingInterface>().data());
scriptEngine->registerGlobalObject("Render", DependencyManager::get<RenderScriptingInterface>().data());
scriptEngine->registerGlobalObject("Engine", _renderEngine->getConfiguration().get());
scriptEngine->registerGlobalObject("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data());
}

View file

@ -67,10 +67,9 @@ public:
void setBlurDeviation(float deviation);
float getBlurDeviation() const { return _parametersBuffer.get<Parameters>().blurInfo.z; }
double getGPUTime() const { return _gpuTimer.getAverage(); }
using JobModel = render::Task::Job::Model<AmbientOcclusionEffect>;
using JobModel = render::Job::Model<AmbientOcclusionEffect>;
private:

View file

@ -22,7 +22,7 @@ public:
Antialiasing();
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<Antialiasing>;
using JobModel = render::Job::Model<Antialiasing>;
const gpu::PipelinePointer& getAntialiasingPipeline();
const gpu::PipelinePointer& getBlendPipeline();

View file

@ -18,7 +18,7 @@
class DebugDeferredBuffer {
public:
using JobModel = render::Task::Job::Model<DebugDeferredBuffer>;
using JobModel = render::Job::Model<DebugDeferredBuffer>;
DebugDeferredBuffer();

View file

@ -17,7 +17,7 @@ public:
HitEffect();
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<HitEffect>;
using JobModel = render::Job::Model<HitEffect>;
const gpu::PipelinePointer& getHitEffectPipeline();

View file

@ -67,7 +67,7 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo
DependencyManager::get<DeferredLightingEffect>()->render(renderContext);
}
void ToneMappingDeferred::configure(const Configuration& configuration) {
void ToneMappingDeferred::configure(const Config& configuration) {
if (configuration.exposure >= 0) {
_toneMappingEffect.setExposure(configuration.curve);
}
@ -81,7 +81,7 @@ void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const Ren
_toneMappingEffect.render(renderContext->getArgs());
}
RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) : Task() {
RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; };
// Prepare the ShapePipelines

View file

@ -22,14 +22,14 @@ class SetupDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<SetupDeferred>;
using JobModel = render::Job::Model<SetupDeferred>;
};
class PrepareDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<PrepareDeferred>;
using JobModel = render::Job::Model<PrepareDeferred>;
};
@ -37,25 +37,28 @@ class RenderDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<RenderDeferred>;
using JobModel = render::Job::Model<RenderDeferred>;
};
class ToneMappingConfiguration : public QObject {
class ToneMappingConfig : public render::Job::Config {
Q_OBJECT
public:
Q_PROPERTY(float exposure MEMBER exposure);
Q_PROPERTY(int curve MEMBER curve);
float exposure;
int curve;
Q_PROPERTY(float exposure MEMBER exposure NOTIFY dirty);
Q_PROPERTY(int curve MEMBER curve NOTIFY dirty);
float exposure{ 0.0 };
int curve{ 3 };
signals:
void dirty();
};
class ToneMappingDeferred {
public:
using Configuration = ToneMappingConfiguration;
void configure(const Configuration&);
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using Config = ToneMappingConfig;
using JobModel = render::Job::Model<ToneMappingDeferred, Config>;
using JobModel = render::Task::Job::Model<ToneMappingDeferred, Configuration>;
void configure(const Config&);
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
ToneMappingEffect _toneMappingEffect;
};
@ -65,7 +68,7 @@ public:
DrawOpaqueDeferred(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
using JobModel = render::Task::Job::ModelI<DrawOpaqueDeferred, render::ItemIDsBounds>;
using JobModel = render::Job::ModelI<DrawOpaqueDeferred, render::ItemIDsBounds>;
protected:
render::ShapePlumberPointer _shapePlumber;
@ -76,7 +79,7 @@ public:
DrawTransparentDeferred(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
using JobModel = render::Task::Job::ModelI<DrawTransparentDeferred, render::ItemIDsBounds>;
using JobModel = render::Job::ModelI<DrawTransparentDeferred, render::ItemIDsBounds>;
protected:
render::ShapePlumberPointer _shapePlumber;
@ -88,7 +91,7 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<DrawStencilDeferred>;
using JobModel = render::Job::Model<DrawStencilDeferred>;
protected:
static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable
@ -98,7 +101,7 @@ class DrawBackgroundDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<DrawBackgroundDeferred>;
using JobModel = render::Job::Model<DrawBackgroundDeferred>;
};
class DrawOverlay3D {
@ -108,7 +111,7 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<DrawOverlay3D>;
using JobModel = render::Job::Model<DrawOverlay3D>;
protected:
static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable
@ -119,7 +122,7 @@ class Blit {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<Blit>;
using JobModel = render::Job::Model<Blit>;
};
class RenderDeferredTask : public render::Task {
@ -128,7 +131,7 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<RenderDeferredTask>;
using JobModel = Model<RenderDeferredTask>;
void setDrawDebugDeferredBuffer(int draw) { enableJob(_drawDebugDeferredBufferIndex, draw >= 0); }
bool doDrawDebugDeferredBuffer() const { return getEnableJob(_drawDebugDeferredBufferIndex); }

View file

@ -78,7 +78,7 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const
});
}
RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) : Task() {
RenderShadowTask::RenderShadowTask(CullFunctor cullFunctor) {
cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; };
// Prepare the ShapePipeline

View file

@ -25,7 +25,7 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext,
const render::ShapesIDsBounds& inShapes);
using JobModel = render::Task::Job::ModelI<RenderShadowMap, render::ShapesIDsBounds>;
using JobModel = render::Job::ModelI<RenderShadowMap, render::ShapesIDsBounds>;
protected:
render::ShapePlumberPointer _shapePlumber;
};
@ -36,7 +36,7 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
using JobModel = render::Task::Job::Model<RenderShadowTask>;
using JobModel = Model<RenderShadowTask>;
};
#endif // hifi_RenderShadowTask_h

View file

@ -38,7 +38,7 @@ namespace render {
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems);
using JobModel = Task::Job::ModelI<DrawStatus, ItemIDsBounds>;
using JobModel = Job::ModelI<DrawStatus, ItemIDsBounds>;
const gpu::PipelinePointer getDrawItemBoundsPipeline();
const gpu::PipelinePointer getDrawItemStatusPipeline();

View file

@ -38,7 +38,7 @@ public:
ProbeNumItems _probeNumItems;
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemIDsBounds& outItems);
using JobModel = Task::Job::ModelO<FetchItems, ItemIDsBounds>;
using JobModel = Job::ModelO<FetchItems, ItemIDsBounds>;
};
template<RenderDetails::Type T = RenderDetails::Type::OTHER_ITEM>
@ -54,7 +54,7 @@ public:
render::cullItems(renderContext, _cullFunctor, details, inItems, outItems);
}
using JobModel = Task::Job::ModelIO<CullItems<T>, ItemIDsBounds, ItemIDsBounds>;
using JobModel = Job::ModelIO<CullItems<T>, ItemIDsBounds, ItemIDsBounds>;
protected:
CullFunctor _cullFunctor;
@ -66,14 +66,14 @@ public:
DepthSortItems(bool frontToBack = true) : _frontToBack(frontToBack) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
using JobModel = Task::Job::ModelIO<DepthSortItems, ItemIDsBounds, ItemIDsBounds>;
using JobModel = Job::ModelIO<DepthSortItems, ItemIDsBounds, ItemIDsBounds>;
};
class DrawLight {
public:
DrawLight(CullFunctor cullFunctor) : _cullFunctor{ cullFunctor } {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
using JobModel = Task::Job::Model<DrawLight>;
using JobModel = Job::Model<DrawLight>;
protected:
CullFunctor _cullFunctor;
@ -82,7 +82,7 @@ protected:
class PipelineSortShapes {
public:
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ShapesIDsBounds& outShapes);
using JobModel = Task::Job::ModelIO<PipelineSortShapes, ItemIDsBounds, ShapesIDsBounds>;
using JobModel = Job::ModelIO<PipelineSortShapes, ItemIDsBounds, ShapesIDsBounds>;
};
class DepthSortShapes {
@ -91,7 +91,7 @@ public:
DepthSortShapes(bool frontToBack = true) : _frontToBack(frontToBack) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapesIDsBounds& inShapes, ShapesIDsBounds& outShapes);
using JobModel = Task::Job::ModelIO<DepthSortShapes, ShapesIDsBounds, ShapesIDsBounds>;
using JobModel = Job::ModelIO<DepthSortShapes, ShapesIDsBounds, ShapesIDsBounds>;
};
}

View file

@ -19,6 +19,9 @@
#include "gpu/Batch.h"
#include <PerfStat.h>
// Prepare Qt for auto configurations
Q_DECLARE_METATYPE(std::shared_ptr<QObject>)
namespace render {
// A varying piece of data, to be used as Job/Task I/O
@ -50,14 +53,18 @@ protected:
std::shared_ptr<Concept> _concept;
};
class NoConfiguration : public QObject {
class JobConfig : public QObject {
Q_OBJECT
};
class DefaultJobConfig: public JobConfig {
Q_OBJECT
};
template <class T, class C> void jobConfigure(T& model, const C& configuration) {
model.configure(configuration);
}
template<class T> void jobConfigure(T&, const NoConfiguration&) {
template<class T> void jobConfigure(T&, const DefaultJobConfig&) {
}
// FIXME: In c++17, use default classes of nullptr_t to combine these
@ -76,12 +83,13 @@ template <class T, class I, class O> void jobRunIO(T& model, const SceneContextP
class Job {
public:
using QObjectPointer = std::shared_ptr<QObject>;
using Config = JobConfig;
using QConfig = std::shared_ptr<QObject>;
// The guts of a job
class Concept {
public:
Concept() = default;
Concept(QConfig config) : _config(config) {}
virtual ~Concept() = default;
bool isEnabled() const { return _isEnabled; }
@ -89,32 +97,31 @@ public:
virtual const Varying getInput() const { return Varying(); }
virtual const Varying getOutput() const { return Varying(); }
virtual const QObjectPointer getConfiguration() = 0;
virtual void setConfiguration(const QObjectPointer& configuration) = 0;
virtual QConfig& getConfiguration() { return _config; }
virtual void applyConfiguration() = 0;
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0;
protected:
QConfig _config;
bool _isEnabled = true;
};
using ConceptPointer = std::shared_ptr<Concept>;
template <class T, class C = NoConfiguration> class Model : public Concept {
template <class T, class C = DefaultJobConfig> class Model : public Concept {
public:
using Data = T;
using ConfigurationPointer = std::shared_ptr<C>;
using Config = C;
Data _data;
ConfigurationPointer _configuration;
Model() : _configuration{ std::make_shared<C>() } {}
Model(Data data) : _data(data), _configuration{ std::make_shared<C>() } {
jobConfigure(_data, *_configuration);
Model(Data data = Data()) : _data(data), Concept(std::make_shared<C>()) {
applyConfiguration();
}
const QObjectPointer getConfiguration() { return _configuration; }
void setConfiguration(const QObjectPointer& configuration) {
_configuration = std::static_pointer_cast<C>(configuration);
jobConfigure(_data, *_configuration);
void applyConfiguration() {
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
@ -124,25 +131,23 @@ public:
}
};
template <class T, class I, class C = NoConfiguration> class ModelI : public Concept {
template <class T, class I, class C = DefaultJobConfig> class ModelI : public Concept {
public:
using Data = T;
using ConfigurationPointer = std::shared_ptr<C>;
using Config = C;
using Input = I;
Data _data;
ConfigurationPointer _configuration;
Varying _input;
const Varying getInput() const { return _input; }
ModelI(const Varying& input, Data data = Data()) : _data(data), _input(input) {}
ModelI(Data data) : _data(data) {}
ModelI(const Varying& input, Data data = Data()) : _input(input), _data(data), Concept(std::make_shared<C>()) {
applyConfiguration();
}
const QObjectPointer getConfiguration() { return _configuration; }
void setConfiguration(const QObjectPointer& configuration) {
_configuration = std::static_pointer_cast<C>(configuration);
jobConfigure(_data, *_configuration);
void applyConfiguration() {
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
@ -152,25 +157,23 @@ public:
}
};
template <class T, class O, class C = NoConfiguration> class ModelO : public Concept {
template <class T, class O, class C = DefaultJobConfig> class ModelO : public Concept {
public:
using Data = T;
using ConfigurationPointer = std::shared_ptr<C>;
using Config = C;
using Output = O;
Data _data;
ConfigurationPointer _configuration;
Varying _output;
const Varying getOutput() const { return _output; }
ModelO(Data data) : _data(data), _output(Output()) {}
ModelO() : _output(Output()) {}
ModelO(Data data = Data()) : _data(data), _output(Output()), Concept(std::make_shared<C>()) {
applyConfiguration();
}
const QObjectPointer getConfiguration() { return _configuration; }
void setConfiguration(const QObjectPointer& configuration) {
_configuration = std::static_pointer_cast<C>(configuration);
jobConfigure(_data, *_configuration);
void applyConfiguration() {
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
@ -180,28 +183,26 @@ public:
}
};
template <class T, class I, class O, class C = NoConfiguration> class ModelIO : public Concept {
template <class T, class I, class O, class C = DefaultJobConfig> class ModelIO : public Concept {
public:
using Data = T;
using ConfigurationPointer = std::shared_ptr<C>;
using Config = C;
using Input = I;
using Output = O;
Data _data;
ConfigurationPointer _configuration;
Varying _input;
Varying _output;
const Varying getInput() const { return _input; }
const Varying getOutput() const { return _output; }
ModelIO(const Varying& input, Data data = Data()) : _data(data), _input(input), _output(Output()) {}
ModelIO(Data data) : _data(data), _output(Output()) {}
ModelIO(const Varying& input, Data data = Data()) : _data(data), _input(input), _output(Output()), Concept(std::make_shared<C>()) {
applyConfiguration();
}
const QObjectPointer getConfiguration() { return _configuration; }
void setConfiguration(const QObjectPointer& configuration) {
_configuration = std::static_pointer_cast<C>(configuration);
jobConfigure(_data, *_configuration);
void applyConfiguration() {
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
@ -211,7 +212,6 @@ public:
}
};
Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {}
bool isEnabled() const { return _concept->isEnabled(); }
@ -219,8 +219,8 @@ public:
const Varying getInput() const { return _concept->getInput(); }
const Varying getOutput() const { return _concept->getOutput(); }
const QObjectPointer getConfiguration() const { return _concept->getConfiguration(); }
void setConfiguration(const QObjectPointer& configuration) { return _concept->setConfiguration(configuration); }
QConfig& getConfiguration() const { return _concept->getConfiguration(); }
void applyConfiguration() { return _concept->applyConfiguration(); }
template <class T> T& edit() {
auto concept = std::static_pointer_cast<typename T::JobModel>(_concept);
@ -235,37 +235,85 @@ public:
_concept->run(sceneContext, renderContext);
}
class Container {
public:
using Job = Job;
using Jobs = std::vector<Job>;
Container() = default;
virtual ~Container() = default;
// Queue a new job to the container; returns the job's output
template <class T, class... A> const Varying addJob(std::string name, A&&... args) {
_jobs.emplace_back(name, std::make_shared<typename T::JobModel>(std::forward<A>(args)...));
return _jobs.back().getOutput();
}
void enableJob(size_t jobIndex, bool enable = true) { _jobs.at(jobIndex).setEnabled(enable); }
bool getEnableJob(size_t jobIndex) const { return _jobs.at(jobIndex).isEnabled(); }
protected:
Jobs _jobs;
};
protected:
friend class Container;
ConceptPointer _concept;
std::string _name = "";
};
// Define our vernacular: Engine->Tasks->Jobs
using Task = Job::Container;
using TaskPointer = std::shared_ptr<Task>;
using Tasks = std::vector<TaskPointer>;
class Task;
class TaskConfig : public QObject {
Q_OBJECT
public:
TaskConfig(Task& task) : _task{ task } {}
public slots:
void refresh() {
qDebug() << "ATTEMPTING REFRESH";
//_task.configure(*this);
}
private:
Task& _task;
};
// A task is a specialized job to run a collection of other jobs
// It is defined with JobModel = Task::Model<T>
class Task {
public:
using QConfig = Job::QConfig;
template <class T> class Model : public Job::Concept {
public:
using Data = T;
using Config = TaskConfig;
Data _data;
Model(Data data = Data()) : _data(data), Concept(std::make_shared<QObject>()) {
_config = _data._config;
}
void applyConfiguration() {
jobConfigure(_data, *_config);
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRun(_data, sceneContext, renderContext);
}
}
};
using Jobs = std::vector<Job>;
Task() : _config{ std::make_shared<TaskConfig>(*this) } {}
// Queue a new job to the container; returns the job's output
template <class T, class... A> const Varying addJob(std::string name, A&&... args) {
_jobs.emplace_back(name, std::make_shared<typename T::JobModel>(std::forward<A>(args)...));
QConfig config = _jobs.back().getConfiguration();
config->setParent(_config.get());
config->setObjectName(name.c_str());
QObject::connect(
config.get(), SIGNAL(dirty()),
_config.get(), SLOT(refresh()));
return _jobs.back().getOutput();
}
QConfig getConfiguration() { return _config; }
void configure(const QObject& configuration) {
for (auto& job : _jobs) {
job.applyConfiguration();
}
}
void enableJob(size_t jobIndex, bool enable = true) { _jobs.at(jobIndex).setEnabled(enable); }
bool getEnableJob(size_t jobIndex) const { return _jobs.at(jobIndex).isEnabled(); }
protected:
template <class T> friend class Model;
QConfig _config;
Jobs _jobs;
};
}