3
0
Fork 0
mirror of https://github.com/lubosz/overte.git synced 2025-04-26 17:35:44 +02:00

MOving forward with the TaskConcept and TaskModel, all working

This commit is contained in:
Sam Cake 2017-04-10 02:30:13 -07:00
parent b65448bcbe
commit a458828590
14 changed files with 195 additions and 155 deletions

View file

@ -50,7 +50,7 @@ using namespace render;
extern void initOverlay3DPipelines(render::ShapePlumber& plumber);
extern void initDeferredPipelines(render::ShapePlumber& plumber);
void RenderDeferredTask::build(render::Task& task, const render::Varying& input, render::Varying& output) {
void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
auto items = input.get<Input>();
// Prepare the ShapePipelines

View file

@ -192,14 +192,14 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer);
};
class RenderDeferredTask : public render::Task {
class RenderDeferredTask {
public:
using Input = RenderFetchCullSortTask::Output;
using JobModel = render::Task::ModelI<RenderDeferredTask, Input>;
RenderDeferredTask() {}
void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs);
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs);
};
#endif // hifi_RenderDeferredTask_h

View file

@ -29,7 +29,7 @@
using namespace render;
extern void initForwardPipelines(ShapePlumber& plumber);
void RenderForwardTask::build(render::Task& task, const render::Varying& input, render::Varying& output) {
void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
auto items = input.get<Input>();
// Prepare the ShapePipelines

View file

@ -16,14 +16,14 @@
#include <render/RenderFetchCullSortTask.h>
#include "LightingModel.h"
class RenderForwardTask : public render::Task {
class RenderForwardTask {
public:
using Input = RenderFetchCullSortTask::Output;
using JobModel = render::Task::ModelI<RenderForwardTask, Input>;
RenderForwardTask() {}
void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs);
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs);
};
class PrepareFramebuffer {

View file

@ -90,7 +90,7 @@ void RenderShadowMap::run(const render::SceneContextPointer& sceneContext, const
});
}
void RenderShadowTask::build(render::Task& task, const render::Varying& input, render::Varying& output, CullFunctor cullFunctor) {
void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, CullFunctor cullFunctor) {
cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; };
// Prepare the ShapePipeline
@ -136,7 +136,7 @@ void RenderShadowTask::build(render::Task& task, const render::Varying& input, r
void RenderShadowTask::configure(const Config& configuration) {
DependencyManager::get<DeferredLightingEffect>()->setShadowMapEnabled(configuration.enabled);
// This is a task, so must still propogate configure() to its Jobs
Task::configure(configuration);
// Task::configure(configuration);
}
void RenderShadowSetup::run(const SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, Output& output) {

View file

@ -41,13 +41,13 @@ signals:
void dirty();
};
class RenderShadowTask : public render::Task {
class RenderShadowTask {
public:
using Config = RenderShadowTaskConfig;
using JobModel = render::Task::Model<RenderShadowTask, Config>;
RenderShadowTask() {}
void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor shouldRender);
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor shouldRender);
void configure(const Config& configuration);
};

View file

@ -17,7 +17,7 @@ using namespace render;
const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" };
void ZoneRendererTask::build(render::Task& task, const Varying& input, Varying& ouput) {
void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) {
const auto zoneItems = task.addJob<render::SelectItems>("FilterZones", input, ZONES_SELECTION.c_str());

View file

@ -27,7 +27,7 @@ signals:
protected:
};
class ZoneRendererTask : public render::Task {
class ZoneRendererTask {
public:
static const render::Selection::Name ZONES_SELECTION;
@ -35,11 +35,11 @@ public:
using Inputs = render::ItemBounds;
using Config = ZoneRendererConfig;
using JobModel = Model<ZoneRendererTask, Config>;
using JobModel = render::Task::ModelI<ZoneRendererTask, Inputs, Config>;
ZoneRendererTask() {}
void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs);
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs);
void configure(const Config& config) { _maxDrawn = config.maxDrawn; }

View file

@ -22,13 +22,22 @@
using namespace render;
Engine::Engine() :
_sceneContext(std::make_shared<SceneContext>()),
_renderContext(std::make_shared<RenderContext>()) {
}
class EngineTask {
public:
void Engine::build() {
addJob<EngineStats>("Stats");
using JobModel = Task::Model<EngineTask>;
EngineTask() {}
void build(JobModel& task, const Varying& in, Varying& out) {
task.addJob<EngineStats>("Stats");
}
};
Engine::Engine() : Task("Engine", EngineTask::JobModel::factoryModel()),
_sceneContext(std::make_shared<SceneContext>()),
_renderContext(std::make_shared<RenderContext>())
{
}
void Engine::load() {

View file

@ -25,7 +25,6 @@ namespace render {
public:
Engine();
void build();
~Engine() = default;
// Load any persisted settings, and set up the presets

View file

@ -17,7 +17,7 @@
using namespace render;
void RenderFetchCullSortTask::build(Task& task, const Varying& input, Varying& output, CullFunctor cullFunctor) {
void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varying& output, CullFunctor cullFunctor) {
cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; };
// CPU jobs:

View file

@ -17,7 +17,7 @@
#include "Task.h"
#include "CullTask.h"
class RenderFetchCullSortTask : public render::Task {
class RenderFetchCullSortTask {
public:
enum Buckets {
@ -38,7 +38,7 @@ public:
RenderFetchCullSortTask() {}
void build(render::Task& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor);
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs, render::CullFunctor cullFunctor);
};
#endif // hifi_RenderFetchCullSortTask_h

View file

@ -21,6 +21,7 @@ void TaskConfig::refresh() {
return;
}
_task->configure(*this);
// _task->configure(*this);
_task->applyConfiguration();
}

View file

@ -301,6 +301,7 @@ public:
};
class Job;
class JobConcept;
class Task;
class JobNoIO {};
@ -432,8 +433,7 @@ public slots:
void refresh();
private:
friend class Task;
Task* _task;
JobConcept* _task;
};
template <class T, class C> void jobConfigure(T& data, const C& configuration) {
@ -458,73 +458,37 @@ template <class T, class I, class O> void jobRun(T& data, const SceneContextPoin
data.run(sceneContext, renderContext, input, output);
}
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 };
// The guts of a job
class JobConcept {
public:
using Persistent = PersistentConfig<GPUJobConfig>;
using Config = JobConfig;
using QConfigPointer = std::shared_ptr<QObject>;
GPUJobConfig() = default;
GPUJobConfig(bool enabled) : JobConfig(enabled) {}
JobConcept(QConfigPointer config) : _config(config) {}
virtual ~JobConcept() = default;
// 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; }
};
virtual const Varying getInput() const { return Varying(); }
virtual const Varying getOutput() const { return Varying(); }
class GPUTaskConfig : public TaskConfig {
Q_OBJECT
Q_PROPERTY(double gpuRunTime READ getGPURunTime)
Q_PROPERTY(double batchRunTime READ getBatchRunTime)
virtual QConfigPointer& getConfiguration() { return _config; }
virtual void applyConfiguration() = 0;
double _msGPURunTime { 0.0 };
double _msBatchRunTime { 0.0 };
public:
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0;
using Persistent = PersistentConfig<GPUTaskConfig>;
protected:
void setCPURunTime(double mstime) { std::static_pointer_cast<Config>(_config)->setCPURunTime(mstime); }
QConfigPointer _config;
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; }
friend class Job;
};
class Job {
public:
using Concept = JobConcept;
using Config = JobConfig;
using QConfigPointer = std::shared_ptr<QObject>;
using None = JobNoIO;
// The guts of a job
class Concept {
public:
Concept(QConfigPointer config) : _config(config) {}
virtual ~Concept() = default;
virtual const Varying getInput() const { return Varying(); }
virtual const Varying getOutput() const { return Varying(); }
virtual QConfigPointer& getConfiguration() { return _config; }
virtual void applyConfiguration() = 0;
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0;
protected:
void setCPURunTime(double mstime) { std::static_pointer_cast<Config>(_config)->setCPURunTime(mstime); }
QConfigPointer _config;
friend class Job;
};
using ConceptPointer = std::shared_ptr<Concept>;
template <class T, class C = Config, class I = None, class O = None> class Model : public Concept {
@ -549,6 +513,12 @@ public:
applyConfiguration();
}
template <class... A>
static std::shared_ptr<Model> factoryModel(const Varying& input, A&&... args) {
return std::make_shared<Model>(input, std::forward<A>(args)...);
}
void applyConfiguration() override {
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
}
@ -593,14 +563,15 @@ protected:
std::string _name = "";
};
template <class T, class... A> void jobBuild(T& data, const Varying& input, Varying& output, A&&... args) {
data.build(*(dynamic_cast<Task*>(&data)), input, output, std::forward<A>(args)...);
}
/*
template <class T, class... A> void taskBuild(T& data, typename T::JobModel* task, const Varying& input, Varying& output, A&&... args) {
data.build(*(task), input, output, std::forward<A>(args)...);
}*/
// A task is a specialized job to run a collection of other jobs
// It is defined with JobModel = Task::Model<T>
class Task {
class Task : public Job {
public:
using Config = TaskConfig;
using QConfigPointer = Job::QConfigPointer;
@ -608,119 +579,179 @@ public:
using Concept = Job::Concept;
using Jobs = std::vector<Job>;
template <class T, class C = Config, class I = None, class O = None> class Model : public Concept {
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 <class NT, class... NA> const Varying addJob(std::string name, const Varying& input, NA&&... args) {
_jobs.emplace_back(name, (NT::JobModel::factoryModel(input, std::forward<NA>(args)...)));
QConfigPointer config = _jobs.back().getConfiguration();
config->setParent(getConfiguration().get());
config->setObjectName(name.c_str());
// Connect loaded->refresh
QObject::connect(config.get(), SIGNAL(loaded()), getConfiguration().get(), SLOT(refresh()));
static const char* DIRTY_SIGNAL = "dirty()";
if (config->metaObject()->indexOfSignal(DIRTY_SIGNAL) != -1) {
// Connect dirty->refresh if defined
QObject::connect(config.get(), SIGNAL(dirty()), getConfiguration().get(), SLOT(refresh()));
}
return _jobs.back().getOutput();
}
template <class NT, class... NA> const Varying addJob(std::string name, NA&&... args) {
const auto input = Varying(typename NT::JobModel::Input());
return addJob<NT>(name, input, std::forward<NA>(args)...);
}
};
template <class T, class C = Config, class I = None, class O = None> class TaskModel : public TaskConcept {
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; }
TaskModel(const Varying& input) :
TaskConcept(input, nullptr),
_data(Data()) {}
template <class... A>
Model(const Varying& input, A&&... args) :
Concept(nullptr),
_data(Data()),
_input(input) {
static std::shared_ptr<TaskModel> factoryModel(const Varying& input, A&&... args) {
auto model = std::make_shared<TaskModel>(input);
jobBuild(_data, _input, _output, std::forward<A>(args)...);
model->_data.build(*(model), model->_input, model->_output, std::forward<A>(args)...);
// Recreate the Config to use the templated type
_data.template createConfiguration<C>();
_config = _data.getConfiguration();
applyConfiguration();
model->createConfiguration();
model->applyConfiguration();
return model;
}
template <class... A>
static std::shared_ptr<TaskModel> factoryModel(A&&... args) {
const auto input = Varying(Input());
return factoryModel(input, std::forward<A>(args)...);
}
void createConfiguration() {
auto config = std::make_shared<C>();
if (_config) {
// Transfer children to the new configuration
auto children = _config->children();
for (auto& child : children) {
child->setParent(config.get());
QObject::connect(child, SIGNAL(loaded()), config.get(), SLOT(refresh()));
static const char* DIRTY_SIGNAL = "dirty()";
if (child->metaObject()->indexOfSignal(DIRTY_SIGNAL) != -1) {
// Connect dirty->refresh if defined
QObject::connect(child, SIGNAL(dirty()), config.get(), SLOT(refresh()));
}
}
}
_config = config;
std::static_pointer_cast<C>(_config)->_task = this;
}
QConfigPointer& getConfiguration() override {
if (!_config) {
createConfiguration();
}
return _config;
}
void applyConfiguration() override {
jobConfigure(_data, *std::static_pointer_cast<C>(_config));
for (auto& job : _jobs) {
job.applyConfiguration();
}
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) override {
auto config = std::static_pointer_cast<C>(_config);
if (config->alwaysEnabled || config->enabled) {
for (auto job : _data._jobs) {
for (auto job : _jobs) {
job.run(sceneContext, renderContext);
}
}
}
};
template <class T, class I, class C = Config> using ModelI = Model<T, C, I, None>;
template <class T, class O, class C = Config> using ModelO = Model<T, C, None, O>;
template <class T, class I, class O, class C = Config> using ModelIO = Model<T, C, I, O>;
template <class T, class C = Config> using Model = TaskModel<T, C, None, None>;
template <class T, class I, class C = Config> using ModelI = TaskModel<T, C, I, None>;
template <class T, class O, class C = Config> using ModelO = TaskModel<T, C, None, O>;
template <class T, class I, class O, class C = Config> using ModelIO = TaskModel<T, C, I, O>;
// Create a new job in the container's queue; returns the job's output
// Create a new job in the Task's queue; returns the job's output
template <class T, class... A> const Varying addJob(std::string name, const Varying& input, A&&... args) {
_jobs.emplace_back(name, std::make_shared<typename T::JobModel>(input, std::forward<A>(args)...));
QConfigPointer config = _jobs.back().getConfiguration();
config->setParent(getConfiguration().get());
config->setObjectName(name.c_str());
// Connect loaded->refresh
QObject::connect(config.get(), SIGNAL(loaded()), getConfiguration().get(), SLOT(refresh()));
static const char* DIRTY_SIGNAL = "dirty()";
if (config->metaObject()->indexOfSignal(DIRTY_SIGNAL) != -1) {
// Connect dirty->refresh if defined
QObject::connect(config.get(), SIGNAL(dirty()), getConfiguration().get(), SLOT(refresh()));
}
return _jobs.back().getOutput();
return std::static_pointer_cast<TaskConcept>( _concept)->addJob<T>(name, input, std::forward<A>(args)...);
}
template <class T, class... A> const Varying addJob(std::string name, A&&... args) {
const auto input = Varying(typename T::JobModel::Input());
return addJob<T>(name, input, std::forward<A>(args)...);
return std::static_pointer_cast<TaskConcept>( _concept)->addJob<T>(name, input, std::forward<A>(args)...);
}
template <class O> void setOutput(O&& output) {
_concept->_output = Varying(output);
}
template <class C> void createConfiguration() {
auto config = std::make_shared<C>();
if (_config) {
// Transfer children to the new configuration
auto children = _config->children();
for (auto& child : children) {
child->setParent(config.get());
QObject::connect(child, SIGNAL(loaded()), config.get(), SLOT(refresh()));
static const char* DIRTY_SIGNAL = "dirty()";
if (child->metaObject()->indexOfSignal(DIRTY_SIGNAL) != -1) {
// Connect dirty->refresh if defined
QObject::connect(child, SIGNAL(dirty()), config.get(), SLOT(refresh()));
}
}
}
_config = config;
std::static_pointer_cast<Config>(_config)->_task = this;
}
std::shared_ptr<Config> getConfiguration() {
if (!_config) {
createConfiguration<Config>();
}
return std::static_pointer_cast<Config>(_config);
return std::static_pointer_cast<Config>(_concept->getConfiguration());
}
void configure(const QObject& configuration) {
for (auto& job : _jobs) {
job.applyConfiguration();
}
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
for (auto job : _jobs) {
job.run(sceneContext, renderContext);
}
}
protected:
};
QConfigPointer _config;
Jobs _jobs;
// 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>;
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>;
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; }
};
}