Promote render::Job to render::Task::Job

This commit is contained in:
Zach Pomerantz 2016-01-06 18:18:21 -08:00
parent 01c9de4f9d
commit 9b4a395f6b
14 changed files with 428 additions and 399 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -51,63 +51,63 @@ void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const Ren
RenderDeferredTask::RenderDeferredTask() : Task() {
// CPU only, create the list of renderedOpaques items
_jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque",
addJob("FetchOpaque", std::make_shared<FetchItems::JobModel>(
FetchItems([](const RenderContextPointer& context, int count) {
context->getItemsConfig().opaque.numFeed = count;
})
)));
_jobs.push_back(Job(new CullItemsOpaque::JobModel("CullOpaque", _jobs.back().getOutput())));
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput())));
));
addJob("CullOpaque", std::make_shared<CullItemsOpaque::JobModel>(_jobs.back().getOutput()));
addJob("DepthSortOpaque", std::make_shared<DepthSortItems::JobModel>(_jobs.back().getOutput()));
auto& renderedOpaques = _jobs.back().getOutput();
// CPU only, create the list of renderedTransparents items
_jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent",
addJob("FetchTransparent", std::make_shared<FetchItems::JobModel>(
FetchItems(ItemFilter::Builder::transparentShape().withoutLayered(),
[](const RenderContextPointer& context, int count) {
context->getItemsConfig().transparent.numFeed = count;
})
)));
_jobs.push_back(Job(new CullItemsTransparent::JobModel("CullTransparent", _jobs.back().getOutput())));
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortTransparent", _jobs.back().getOutput(), DepthSortItems(false))));
));
addJob("CullTransparent", std::make_shared<CullItemsTransparent::JobModel>(_jobs.back().getOutput()));
addJob("DepthSortTransparent", std::make_shared<DepthSortItems::JobModel>(_jobs.back().getOutput(), DepthSortItems(false)));
auto& renderedTransparents = _jobs.back().getOutput();
// GPU Jobs: Start preparing the deferred and lighting buffer
_jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred")));
addJob("PrepareDeferred", std::make_shared<PrepareDeferred::JobModel>());
// Render opaque objects in DeferredBuffer
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", renderedOpaques)));
addJob("DrawOpaqueDeferred", std::make_shared<DrawOpaqueDeferred::JobModel>(renderedOpaques));
// Once opaque is all rendered create stencil background
_jobs.push_back(Job(new DrawStencilDeferred::JobModel("DrawOpaqueStencil")));
addJob("DrawOpaqueStencil", std::make_shared<DrawStencilDeferred::JobModel>());
// Use Stencil and start drawing background in Lighting buffer
_jobs.push_back(Job(new DrawBackgroundDeferred::JobModel("DrawBackgroundDeferred")));
addJob("DrawBackgroundDeferred", std::make_shared<DrawBackgroundDeferred::JobModel>());
// Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now.
_jobs.push_back(Job(new DrawLight::JobModel("DrawLight")));
addJob("DrawLight", std::make_shared<DrawLight::JobModel>());
// DeferredBuffer is complete, now let's shade it into the LightingBuffer
_jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred")));
addJob("RenderDeferred", std::make_shared<RenderDeferred::JobModel>());
// AO job, to be revisited
_jobs.push_back(Job(new AmbientOcclusion::JobModel("AmbientOcclusion")));
addJob("AmbientOcclusion", std::make_shared<AmbientOcclusion::JobModel>());
_jobs.back().setEnabled(false);
_occlusionJobIndex = (int)_jobs.size() - 1;
// AA job to be revisited
_jobs.push_back(Job(new Antialiasing::JobModel("Antialiasing")));
addJob("Antialiasing", std::make_shared<Antialiasing::JobModel>());
_jobs.back().setEnabled(false);
_antialiasingJobIndex = (int)_jobs.size() - 1;
// Render transparent objects forward in LigthingBuffer
_jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", renderedTransparents)));
addJob("TransparentDeferred", std::make_shared<DrawTransparentDeferred::JobModel>(renderedTransparents));
// Lighting Buffer ready for tone mapping
_jobs.push_back(Job(new ToneMappingDeferred::JobModel("ToneMapping")));
addJob("ToneMapping", std::make_shared<ToneMappingDeferred::JobModel>());
_toneMappingJobIndex = (int)_jobs.size() - 1;
// Debugging Deferred buffer job
_jobs.push_back(Job(new DebugDeferredBuffer::JobModel("DebugDeferredBuffer")));
addJob("DebugDeferredBuffer", std::make_shared<DebugDeferredBuffer::JobModel>());
_jobs.back().setEnabled(false);
_drawDebugDeferredBufferIndex = (int)_jobs.size() - 1;
@ -116,18 +116,18 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
// Grab a texture map representing the different status icons and assign that to the drawStatsuJob
auto iconMapPath = PathUtils::resourcesPath() + "icons/statusIconAtlas.svg";
auto statusIconMap = DependencyManager::get<TextureCache>()->getImageTexture(iconMapPath);
_jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques, DrawStatus(statusIconMap))));
addJob("DrawStatus", std::make_shared<DrawStatus::JobModel>(renderedOpaques, DrawStatus(statusIconMap)));
_jobs.back().setEnabled(false);
_drawStatusJobIndex = (int)_jobs.size() - 1;
}
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
addJob("DrawOverlay3D", std::make_shared<DrawOverlay3D::JobModel>());
_jobs.push_back(Job(new HitEffect::JobModel("HitEffect")));
addJob("HitEffect", std::make_shared<HitEffect::JobModel>());
_jobs.back().setEnabled(false);
_drawHitEffectJobIndex = (int)_jobs.size() -1;
_jobs.push_back(Job(new Blit::JobModel("Blit")));
addJob("Blit", std::make_shared<Blit::JobModel>());
}
RenderDeferredTask::~RenderDeferredTask() {

View file

@ -22,14 +22,14 @@ class SetupDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<SetupDeferred> JobModel;
using JobModel = render::Task::Job::Model<SetupDeferred>;
};
class PrepareDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<PrepareDeferred> JobModel;
using JobModel = render::Task::Job::Model<PrepareDeferred>;
};
@ -37,7 +37,7 @@ class RenderDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<RenderDeferred> JobModel;
using JobModel = render::Task::Job::Model<RenderDeferred>;
};
class ToneMappingDeferred {
@ -46,21 +46,21 @@ public:
ToneMappingEffect _toneMappingEffect;
typedef render::Job::Model<ToneMappingDeferred> JobModel;
using JobModel = render::Task::Job::Model<ToneMappingDeferred>;
};
class DrawOpaqueDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
typedef render::Job::ModelI<DrawOpaqueDeferred, render::ItemIDsBounds> JobModel;
using JobModel = render::Task::Job::ModelI<DrawOpaqueDeferred, render::ItemIDsBounds>;
};
class DrawTransparentDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems);
typedef render::Job::ModelI<DrawTransparentDeferred, render::ItemIDsBounds> JobModel;
using JobModel = render::Task::Job::ModelI<DrawTransparentDeferred, render::ItemIDsBounds>;
};
class DrawStencilDeferred {
@ -70,14 +70,14 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<DrawStencilDeferred> JobModel;
using JobModel = render::Task::Job::Model<DrawStencilDeferred>;
};
class DrawBackgroundDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<DrawBackgroundDeferred> JobModel;
using JobModel = render::Task::Job::Model<DrawBackgroundDeferred>;
};
class DrawOverlay3D {
@ -86,15 +86,15 @@ public:
static const gpu::PipelinePointer& getOpaquePipeline();
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<DrawOverlay3D> JobModel;
using JobModel = render::Task::Job::Model<DrawOverlay3D>;
};
class Blit {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<Blit> JobModel;
using JobModel = render::Task::Job::Model<Blit>;
};
class RenderDeferredTask : public render::Task {
@ -103,7 +103,7 @@ public:
RenderDeferredTask();
~RenderDeferredTask();
render::Jobs _jobs;
render::Task::Jobs _jobs;
int _drawDebugDeferredBufferIndex = -1;
int _drawStatusJobIndex = -1;

View file

@ -0,0 +1,30 @@
//
// Context.cpp
// 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
//
#include "Context.h"
using namespace render;
RenderContext::RenderContext(ItemsConfig items, Tone tone, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode)
: _deferredDebugMode{ deferredDebugMode }, _deferredDebugSize{ deferredDebugSize },
_args{ nullptr },
_drawStatus{ drawStatus }, _drawHitEffect{ drawHitEffect },
_items{ items }, _tone{ tone } {}
void RenderContext::setOptions(bool occlusion, bool fxaa, bool showOwned) {
_occlusionStatus = occlusion;
_fxaaStatus = fxaa;
if (showOwned) {
_drawStatus |= render::showNetworkStatusFlag;
}
};

View file

@ -0,0 +1,112 @@
//
// Engine.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 render {
class SceneContext {
public:
ScenePointer _scene;
SceneContext() {}
};
using SceneContextPointer = std::shared_ptr<SceneContext>;
// see examples/utilities/tools/renderEngineDebug.js
const int showDisplayStatusFlag = 1;
const int showNetworkStatusFlag = 2;
class RenderContext {
public:
class ItemsConfig {
public:
class Counter {
public:
Counter() {};
Counter(const Counter& counter) {
numFeed = numDrawn = 0;
maxDrawn = counter.maxDrawn;
};
void setCounts(const Counter& counter) {
numFeed = counter.numFeed;
numDrawn = counter.numDrawn;
};
int numFeed = 0;
int numDrawn = 0;
int maxDrawn = -1;
};
class State : public Counter {
public:
bool render = true;
bool cull = true;
bool sort = true;
Counter counter{};
};
ItemsConfig(State opaqueState, State transparentState, Counter overlay3DCounter)
: opaque{ opaqueState }, transparent{ transparentState }, overlay3D{ overlay3DCounter } {}
ItemsConfig() : ItemsConfig{ {}, {}, {} } {}
// TODO: If member count increases, store counters in a map instead of multiple members
State opaque{};
State transparent{};
Counter overlay3D{};
};
class Tone {
public:
int toneCurve = 1; // Means just Gamma 2.2 correction
float exposure = 0.0;
};
RenderContext(ItemsConfig items, Tone tone, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode);
RenderContext() : RenderContext({}, {}, {}, {}, {}, {}) {};
void setArgs(RenderArgs* args) { _args = args; }
inline RenderArgs* getArgs() { return _args; }
inline ItemsConfig& getItemsConfig() { return _items; }
inline Tone& getTone() { return _tone; }
inline int getDrawStatus() { return _drawStatus; }
inline bool getDrawHitEffect() { return _drawHitEffect; }
inline bool getOcclusionStatus() { return _occlusionStatus; }
inline bool getFxaaStatus() { return _fxaaStatus; }
void setOptions(bool occlusion, bool fxaa, bool showOwned);
// Debugging
int _deferredDebugMode;
glm::vec4 _deferredDebugSize;
protected:
RenderArgs* _args;
// Options
int _drawStatus; // bitflag
bool _drawHitEffect;
bool _occlusionStatus = false;
bool _fxaaStatus = false;
ItemsConfig _items;
Tone _tone;
};
typedef std::shared_ptr<RenderContext> RenderContextPointer;
}
#endif // hifi_render_Context_h

View file

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

View file

@ -22,11 +22,9 @@
using namespace render;
DrawSceneTask::DrawSceneTask() : Task() {
}
DrawSceneTask::DrawSceneTask() : Task() {}
DrawSceneTask::~DrawSceneTask() {
}
DrawSceneTask::~DrawSceneTask() {}
void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
// sanity checks
@ -35,7 +33,6 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon
return;
}
// Is it possible that we render without a viewFrustum ?
if (!(renderContext->getArgs() && renderContext->getArgs()->_viewFrustum)) {
return;
@ -46,13 +43,6 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon
}
};
Job::~Job() {
}
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
@ -297,16 +287,3 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo
});
args->_batch = nullptr;
}
void ItemMaterialBucketMap::insert(const ItemID& id, const model::MaterialKey& key) {
// Insert the itemID in every bucket where it filters true
for (auto& bucket : (*this)) {
if (bucket.first.test(key)) {
bucket.second.push_back(id);
}
}
}
void ItemMaterialBucketMap::allocateStandardMaterialBuckets() {
(*this)[model::MaterialFilter::Builder::opaqueDiffuse()];
}

View file

@ -9,217 +9,15 @@
// 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
#ifndef hifi_render_DrawTask_h
#define hifi_render_DrawTask_h
#include "Engine.h"
#include "gpu/Batch.h"
#include <PerfStat.h>
namespace render {
template <class T> void jobRun(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
jobModel.run(sceneContext, renderContext);
}
template <class T, class I> void jobRunI(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) {
jobModel.run(sceneContext, renderContext, input);
}
template <class T, class O> void jobRunO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) {
jobModel.run(sceneContext, renderContext, output);
}
template <class T, class I, class O> void jobRunIO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) {
jobModel.run(sceneContext, renderContext, input, output);
}
class Job {
public:
// Varying represent a varying piece of data
class Varying {
public:
Varying(const Varying& var): _concept(var._concept) {}
Varying() {}
template <class T>
Varying(const T& data) : _concept(std::make_shared<Job::Varying::Model<T>>(data)) {}
// Access the _data contained win the concept explicitely
template <class T> T& edit() { return std::static_pointer_cast<Model<T>>(_concept)->_data; }
template <class T> const T& get() const { return std::static_pointer_cast<const Model<T>>(_concept)->_data; }
protected:
friend class Job;
std::vector<std::weak_ptr<Job>> _consumerJobs;
void addJobConsumer(const std::shared_ptr<Job>& job) {
_consumerJobs.push_back(job);
}
class Concept {
public:
virtual ~Concept() = default;
};
template <class T> class Model : public Concept {
public:
typedef T Data;
Data _data;
Model(const Model& source): _data(source.data) {}
Model(const Data& data): _data(data) {}
virtual ~Model() {}
};
std::shared_ptr<Concept> _concept;
};
Job(const Job& other) : _concept(other._concept) {}
~Job();
bool isEnabled() const { return _concept->isEnabled(); }
void setEnabled(bool isEnabled) { _concept->setEnabled(isEnabled); }
const std::string& getName() const { return _concept->getName(); }
const Varying getInput() const { return _concept->getInput(); }
const Varying getOutput() const { return _concept->getOutput(); }
template <class T> T& edit() {
auto theConcept = std::dynamic_pointer_cast<typename T::JobModel>(_concept);
assert(theConcept);
return theConcept->_data;
}
template <class T> const T& get() const {
auto theConcept = std::dynamic_pointer_cast<typename T::JobModel>(_concept);
assert(theConcept);
return theConcept->_data;
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
PerformanceTimer perfTimer(getName().c_str());
PROFILE_RANGE(getName().c_str());
_concept->run(sceneContext, renderContext);
}
protected:
public:
class Concept {
std::string _name;
bool _isEnabled = true;
public:
Concept() : _name() {}
Concept(const std::string& name) : _name(name) {}
virtual ~Concept() = default;
void setName(const std::string& name) { _name = name; }
const std::string& getName() const { return _name; }
bool isEnabled() const { return _isEnabled; }
void setEnabled(bool isEnabled) { _isEnabled = isEnabled; }
virtual const Varying getInput() const { return Varying(); }
virtual const Varying getOutput() const { return Varying(); }
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0;
};
Job(Concept* concept) : _concept(concept) {}
public:
template <class T> class Model : public Concept {
public:
typedef T Data;
Data _data;
Model() {}
Model(const std::string& name): Concept(name) {}
Model(Data data): _data(data) {}
Model(Data data, const std::string& name): Concept(name), _data(data) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRun(_data, sceneContext, renderContext);
}
}
};
template <class T, class I> class ModelI : public Concept {
public:
typedef T Data;
typedef I Input;
Data _data;
Varying _input;
const Varying getInput() const { return _input; }
ModelI(const std::string& name, const Varying& input, Data data = Data()) : Concept(name), _data(data), _input(input) {}
ModelI(const std::string& name, Data data): Concept(name), _data(data) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRunI(_data, sceneContext, renderContext, _input.get<I>());
}
}
};
template <class T, class O> class ModelO : public Concept {
public:
typedef T Data;
typedef O Output;
Data _data;
Varying _output;
const Varying getOutput() const { return _output; }
ModelO(const std::string& name): Concept(name), _output(Output()) {
}
ModelO(const std::string& name, Data data): Concept(name), _data(data), _output(Output()) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRunO(_data, sceneContext, renderContext, _output.edit<O>());
}
}
};
template <class T, class I, class O> class ModelIO : public Concept {
public:
typedef T Data;
typedef I Input;
typedef O Output;
Data _data;
Varying _input;
Varying _output;
const Varying getInput() const { return _input; }
const Varying getOutput() const { return _output; }
ModelIO(const std::string& name, const Varying& input, Data data = Data()): Concept(name), _data(data), _input(input), _output(Output()) {}
ModelIO(const std::string& name, Data data, Output output): Concept(name), _data(data), _output(output) {}
void setInput(const Varying& input) { _input = input; }
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRunIO(_data, sceneContext, renderContext, _input.get<I>(), _output.edit<O>());
}
}
};
std::shared_ptr<Concept> _concept;
};
typedef std::vector<Job> Jobs;
void cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
void depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
void renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, int maxDrawnItems = -1);
@ -236,25 +34,25 @@ public:
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemIDsBounds& outItems);
typedef Job::ModelO<FetchItems, ItemIDsBounds> JobModel;
using JobModel = Task::Job::ModelO<FetchItems, ItemIDsBounds>;
};
class CullItems {
public:
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
typedef Job::ModelIO<CullItems, ItemIDsBounds, ItemIDsBounds> JobModel;
using JobModel = Task::Job::ModelIO<CullItems, ItemIDsBounds, ItemIDsBounds>;
};
class CullItemsOpaque {
public:
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
typedef Job::ModelIO<CullItemsOpaque, ItemIDsBounds, ItemIDsBounds> JobModel;
using JobModel = Task::Job::ModelIO<CullItemsOpaque, ItemIDsBounds, ItemIDsBounds>;
};
class CullItemsTransparent {
public:
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems);
typedef Job::ModelIO<CullItemsTransparent, ItemIDsBounds, ItemIDsBounds> JobModel;
using JobModel = Task::Job::ModelIO<CullItemsTransparent, ItemIDsBounds, ItemIDsBounds>;
};
class DepthSortItems {
@ -265,14 +63,14 @@ public:
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems);
typedef Job::ModelIO<DepthSortItems, ItemIDsBounds, ItemIDsBounds> JobModel;
using JobModel = Task::Job::ModelIO<DepthSortItems, ItemIDsBounds, ItemIDsBounds>;
};
class DrawLight {
public:
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext);
typedef Job::Model<DrawLight> JobModel;
using JobModel = Task::Job::Model<DrawLight>;
};
class DrawBackground {
@ -296,7 +94,6 @@ public:
};
// A map of ItemIDs allowing to create bucket lists of SHAPE type items which are filtered by their
// Material
class ItemMaterialBucketMap : public std::map<model::MaterialFilter, ItemIDs, model::MaterialFilter::Less> {
@ -313,4 +110,4 @@ void materialSortItems(const SceneContextPointer& sceneContext, const RenderCont
}
#endif // hifi_render_Task_h
#endif // hifi_render_DrawTask_h

View file

@ -8,26 +8,13 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "Engine.h"
#include "DrawTask.h"
using namespace render;
RenderContext::RenderContext(ItemsConfig items, Tone tone, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode)
: _deferredDebugMode{ deferredDebugMode }, _deferredDebugSize{ deferredDebugSize },
_args{ nullptr },
_drawStatus{ drawStatus }, _drawHitEffect{ drawHitEffect },
_items{ items }, _tone{ tone } {}
void RenderContext::setOptions(bool occlusion, bool fxaa, bool showOwned) {
_occlusionStatus = occlusion;
_fxaaStatus = fxaa;
if (showOwned) {
_drawStatus |= render::showNetworkStatusFlag;
}
};
Engine::Engine() :
_sceneContext(std::make_shared<SceneContext>()),
_renderContext(std::make_shared<RenderContext>())
@ -49,6 +36,7 @@ void Engine::addTask(const TaskPointer& task) {
}
void Engine::run() {
// TODO: Tasks will need to be specified such that their data can feed into each other
for (auto task : _tasks) {
task->run(_sceneContext, _renderContext);
}

View file

@ -12,115 +12,11 @@
#ifndef hifi_render_Engine_h
#define hifi_render_Engine_h
#include "Scene.h"
#include "Context.h"
#include "Task.h"
namespace render {
class SceneContext {
public:
ScenePointer _scene;
SceneContext() {}
};
using SceneContextPointer = std::shared_ptr<SceneContext>;
// see examples/utilities/tools/renderEngineDebug.js
const int showDisplayStatusFlag = 1;
const int showNetworkStatusFlag = 2;
class RenderContext {
public:
class ItemsConfig {
public:
class Counter {
public:
Counter() {};
Counter(const Counter& counter) {
numFeed = numDrawn = 0;
maxDrawn = counter.maxDrawn;
};
void setCounts(const Counter& counter) {
numFeed = counter.numFeed;
numDrawn = counter.numDrawn;
};
int numFeed = 0;
int numDrawn = 0;
int maxDrawn = -1;
};
class State : public Counter {
public:
bool render = true;
bool cull = true;
bool sort = true;
Counter counter{};
};
ItemsConfig(State opaqueState, State transparentState, Counter overlay3DCounter)
: opaque{ opaqueState }, transparent{ transparentState }, overlay3D{ overlay3DCounter } {}
ItemsConfig() : ItemsConfig{ {}, {}, {} } {}
// TODO: If member count increases, store counters in a map instead of multiple members
State opaque{};
State transparent{};
Counter overlay3D{};
};
class Tone {
public:
int toneCurve = 1; // Means just Gamma 2.2 correction
float exposure = 0.0;
};
RenderContext(ItemsConfig items, Tone tone, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode);
RenderContext() : RenderContext({}, {}, {}, {}, {}, {}) {};
void setArgs(RenderArgs* args) { _args = args; }
inline RenderArgs* getArgs() { return _args; }
inline ItemsConfig& getItemsConfig() { return _items; }
inline Tone& getTone() { return _tone; }
inline int getDrawStatus() { return _drawStatus; }
inline bool getDrawHitEffect() { return _drawHitEffect; }
inline bool getOcclusionStatus() { return _occlusionStatus; }
inline bool getFxaaStatus() { return _fxaaStatus; }
void setOptions(bool occlusion, bool fxaa, bool showOwned);
// Debugging
int _deferredDebugMode;
glm::vec4 _deferredDebugSize;
protected:
RenderArgs* _args;
// Options
int _drawStatus; // bitflag
bool _drawHitEffect;
bool _occlusionStatus = false;
bool _fxaaStatus = false;
ItemsConfig _items;
Tone _tone;
};
typedef std::shared_ptr<RenderContext> RenderContextPointer;
// The base class for a task that runs on the SceneContext
class Task {
public:
Task() {}
~Task() {}
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {}
protected:
};
typedef std::shared_ptr<Task> TaskPointer;
typedef std::vector<TaskPointer> Tasks;
// The root of the tasks, the Engine, should not be known from the Tasks,
// The SceneContext is what navigates from the engine down to the Tasks
class Engine {
@ -146,7 +42,6 @@ public:
void buildStandardTaskPipeline();
protected:
Tasks _tasks;
SceneContextPointer _sceneContext;
@ -157,3 +52,4 @@ typedef std::shared_ptr<Engine> EnginePointer;
}
#endif // hifi_render_Engine_h

View file

@ -0,0 +1,229 @@
//
// Task.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_Task_h
#define hifi_render_Task_h
#include "Context.h"
#include "gpu/Batch.h"
#include <PerfStat.h>
namespace render {
// A varying piece of data, to be used as Job/Task I/O
// TODO: Task IO
class Varying {
public:
Varying() {}
Varying(const Varying& var) : _concept(var._concept) {}
template <class T> Varying(const T& data) : _concept(std::make_shared<Model<T>>(data)) {}
template <class T> T& edit() { return std::static_pointer_cast<Model<T>>(_concept)->_data; }
template <class T> const T& get() { return std::static_pointer_cast<const Model<T>>(_concept)->_data; }
protected:
class Concept {
public:
virtual ~Concept() = default;
};
template <class T> class Model : public Concept {
public:
using Data = T;
Model(const Data& data) : _data(data) {}
virtual ~Model() = default;
Data _data;
};
std::shared_ptr<Concept> _concept;
};
// FIXME: In c++17, use default classes of nullptr_t to combine these
template <class T> void jobRun(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
jobModel.run(sceneContext, renderContext);
}
template <class T, class I> void jobRunI(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) {
jobModel.run(sceneContext, renderContext, input);
}
template <class T, class O> void jobRunO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) {
jobModel.run(sceneContext, renderContext, output);
}
template <class T, class I, class O> void jobRunIO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input, O& output) {
jobModel.run(sceneContext, renderContext, input, output);
}
// The base class for a task that runs on the SceneContext
class Task {
public:
// The guts of a task; tasks are composed of multiple Jobs that execute serially
class Job {
public:
friend class Task;
// The guts of a job; jobs are composed of a concept
class Concept {
public:
Concept() = default;
virtual ~Concept() = default;
bool isEnabled() const { return _isEnabled; }
void setEnabled(bool isEnabled) { _isEnabled = isEnabled; }
virtual const Varying getInput() const { return Varying(); }
virtual const Varying getOutput() const { return Varying(); }
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0;
protected:
bool _isEnabled = true;
};
using ConceptPointer = std::shared_ptr<Concept>;
template <class T> class Model : public Concept {
public:
typedef T Data;
Data _data;
Model() {}
Model(Data data): _data(data) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRun(_data, sceneContext, renderContext);
}
}
};
template <class T, class I> class ModelI : public Concept {
public:
typedef T Data;
typedef I Input;
Data _data;
Varying _input;
const Varying getInput() const { return _input; }
ModelI(const Varying& input, Data data = Data()) : _data(data), _input(input) {}
ModelI(Data data) : _data(data) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRunI(_data, sceneContext, renderContext, _input.get<I>());
}
}
};
template <class T, class O> class ModelO : public Concept {
public:
typedef T Data;
typedef O Output;
Data _data;
Varying _output;
const Varying getOutput() const { return _output; }
ModelO(Data data) : _data(data), _output(Output()) {}
ModelO() : _output(Output()) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRunO(_data, sceneContext, renderContext, _output.edit<O>());
}
}
};
template <class T, class I, class O> class ModelIO : public Concept {
public:
typedef T Data;
typedef I Input;
typedef O Output;
Data _data;
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()) {}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
if (isEnabled()) {
jobRunIO(_data, sceneContext, renderContext, _input.get<I>(), _output.edit<O>());
}
}
};
Job(ConceptPointer concept) : _concept(concept) {}
Job(std::string name, ConceptPointer concept) : _name(name), _concept(concept) {}
bool isEnabled() const { return _concept->isEnabled(); }
void setEnabled(bool isEnabled) { _concept->setEnabled(isEnabled); }
const Varying getInput() const { return _concept->getInput(); }
const Varying getOutput() const { return _concept->getOutput(); }
template <class T> T& edit() {
auto concept = std::static_pointer_cast<typename T::JobModel>(_concept);
assert(concept);
return concept->_data;
}
template <class T> const T& get() const {
auto concept = std::static_pointer_cast<typename T::JobModel>(_concept);
assert(concept);
return concept->_data;
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
PerformanceTimer perfTimer(_name.c_str());
PROFILE_RANGE(_name.c_str());
_concept->run(sceneContext, renderContext);
}
protected:
ConceptPointer _concept;
std::string _name = "";
};
using Jobs = std::vector<Job>;
public:
using VaryingPointer = std::shared_ptr<Varying>;
Task() {}
~Task() {}
// Queue a new job to the task; returns the job's index
template <class T> size_t addJob(std::string name, std::shared_ptr<T> jobConcept)
{ size_t size = _jobs.size(); _jobs.emplace_back(name, jobConcept); return size; }
template <class T> size_t addJob(std::shared_ptr<T> jobConcept)
{ size_t size = _jobs.size(); _jobs.emplace_back(jobConcept); return size; }
const Job& getJob(size_t i) const { return _jobs.at(i); }
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {}
protected:
Jobs _jobs;
};
typedef std::shared_ptr<Task> TaskPointer;
typedef std::vector<TaskPointer> Tasks;
}
#endif // hifi_render_Task_h