diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.h b/libraries/render-utils/src/AmbientOcclusionEffect.h index 6153795ea6..55970a2d6e 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.h +++ b/libraries/render-utils/src/AmbientOcclusionEffect.h @@ -22,7 +22,7 @@ public: AmbientOcclusion(); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; const gpu::PipelinePointer& getOcclusionPipeline(); const gpu::PipelinePointer& getHBlurPipeline(); diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h index c7cce4cb15..51a8e3a1de 100644 --- a/libraries/render-utils/src/AntialiasingEffect.h +++ b/libraries/render-utils/src/AntialiasingEffect.h @@ -22,7 +22,7 @@ public: Antialiasing(); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; const gpu::PipelinePointer& getAntialiasingPipeline(); const gpu::PipelinePointer& getBlendPipeline(); diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h index 682888b2af..c9ea24644a 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.h +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -18,7 +18,7 @@ class DebugDeferredBuffer { public: - using JobModel = render::Job::Model; + using JobModel = render::Task::Job::Model; DebugDeferredBuffer(); diff --git a/libraries/render-utils/src/HitEffect.h b/libraries/render-utils/src/HitEffect.h index 0a96a5300d..a83fb36693 100644 --- a/libraries/render-utils/src/HitEffect.h +++ b/libraries/render-utils/src/HitEffect.h @@ -17,7 +17,7 @@ public: HitEffect(); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; const gpu::PipelinePointer& getHitEffectPipeline(); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 1b1d08f353..9c286ba204 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -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([](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(_jobs.back().getOutput())); + addJob("DepthSortOpaque", std::make_shared(_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(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(_jobs.back().getOutput())); + addJob("DepthSortTransparent", std::make_shared(_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()); // Render opaque objects in DeferredBuffer - _jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", renderedOpaques))); + addJob("DrawOpaqueDeferred", std::make_shared(renderedOpaques)); // Once opaque is all rendered create stencil background - _jobs.push_back(Job(new DrawStencilDeferred::JobModel("DrawOpaqueStencil"))); + addJob("DrawOpaqueStencil", std::make_shared()); // Use Stencil and start drawing background in Lighting buffer - _jobs.push_back(Job(new DrawBackgroundDeferred::JobModel("DrawBackgroundDeferred"))); + addJob("DrawBackgroundDeferred", std::make_shared()); // 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()); // DeferredBuffer is complete, now let's shade it into the LightingBuffer - _jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred"))); + addJob("RenderDeferred", std::make_shared()); // AO job, to be revisited - _jobs.push_back(Job(new AmbientOcclusion::JobModel("AmbientOcclusion"))); + addJob("AmbientOcclusion", std::make_shared()); _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()); _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(renderedTransparents)); // Lighting Buffer ready for tone mapping - _jobs.push_back(Job(new ToneMappingDeferred::JobModel("ToneMapping"))); + addJob("ToneMapping", std::make_shared()); _toneMappingJobIndex = (int)_jobs.size() - 1; // Debugging Deferred buffer job - _jobs.push_back(Job(new DebugDeferredBuffer::JobModel("DebugDeferredBuffer"))); + addJob("DebugDeferredBuffer", std::make_shared()); _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()->getImageTexture(iconMapPath); - _jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques, DrawStatus(statusIconMap)))); + addJob("DrawStatus", std::make_shared(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()); - _jobs.push_back(Job(new HitEffect::JobModel("HitEffect"))); + addJob("HitEffect", std::make_shared()); _jobs.back().setEnabled(false); _drawHitEffectJobIndex = (int)_jobs.size() -1; - _jobs.push_back(Job(new Blit::JobModel("Blit"))); + addJob("Blit", std::make_shared()); } RenderDeferredTask::~RenderDeferredTask() { diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 051faa3238..330a1cceae 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -22,14 +22,14 @@ class SetupDeferred { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; }; class PrepareDeferred { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; }; @@ -37,7 +37,7 @@ class RenderDeferred { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; }; class ToneMappingDeferred { @@ -46,21 +46,21 @@ public: ToneMappingEffect _toneMappingEffect; - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; }; class DrawOpaqueDeferred { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems); - typedef render::Job::ModelI JobModel; + using JobModel = render::Task::Job::ModelI; }; class DrawTransparentDeferred { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const render::ItemIDsBounds& inItems); - typedef render::Job::ModelI JobModel; + using JobModel = render::Task::Job::ModelI; }; class DrawStencilDeferred { @@ -70,14 +70,14 @@ public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; }; class DrawBackgroundDeferred { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; }; 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 JobModel; + + using JobModel = render::Task::Job::Model; }; class Blit { public: void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - typedef render::Job::Model JobModel; + using JobModel = render::Task::Job::Model; }; 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; diff --git a/libraries/render/src/render/Context.cpp b/libraries/render/src/render/Context.cpp new file mode 100644 index 0000000000..4f7895e4fc --- /dev/null +++ b/libraries/render/src/render/Context.cpp @@ -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; + } +}; + diff --git a/libraries/render/src/render/Context.h b/libraries/render/src/render/Context.h new file mode 100644 index 0000000000..5f8ca60ddb --- /dev/null +++ b/libraries/render/src/render/Context.h @@ -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; + +// 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 RenderContextPointer; + +} + +#endif // hifi_render_Context_h + diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h index 1239819911..c9cf16c0cb 100644 --- a/libraries/render/src/render/DrawStatus.h +++ b/libraries/render/src/render/DrawStatus.h @@ -38,7 +38,7 @@ namespace render { void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems); - typedef Job::ModelI JobModel; + using JobModel = Task::Job::ModelI; const gpu::PipelinePointer getDrawItemBoundsPipeline(); const gpu::PipelinePointer getDrawItemStatusPipeline(); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 44ba57143f..6b35e06a92 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -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()]; -} diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index ab102e32a7..3027cde73f 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -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 namespace render { -template void jobRun(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - jobModel.run(sceneContext, renderContext); -} -template void jobRunI(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) { - jobModel.run(sceneContext, renderContext, input); -} -template void jobRunO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) { - jobModel.run(sceneContext, renderContext, output); -} -template 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 - Varying(const T& data) : _concept(std::make_shared>(data)) {} - - // Access the _data contained win the concept explicitely - template T& edit() { return std::static_pointer_cast>(_concept)->_data; } - template const T& get() const { return std::static_pointer_cast>(_concept)->_data; } - - protected: - friend class Job; - - std::vector> _consumerJobs; - - void addJobConsumer(const std::shared_ptr& job) { - _consumerJobs.push_back(job); - } - - class Concept { - public: - virtual ~Concept() = default; - }; - template 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; - }; - - 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 T& edit() { - auto theConcept = std::dynamic_pointer_cast(_concept); - assert(theConcept); - return theConcept->_data; - } - template const T& get() const { - auto theConcept = std::dynamic_pointer_cast(_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 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 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()); - } - } - }; - - template 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()); - } - } - }; - - template 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(), _output.edit()); - } - } - }; - - std::shared_ptr _concept; -}; - - - - -typedef std::vector 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 JobModel; + using JobModel = Task::Job::ModelO; }; class CullItems { public: void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); - typedef Job::ModelIO JobModel; + using JobModel = Task::Job::ModelIO; }; class CullItemsOpaque { public: void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); - typedef Job::ModelIO JobModel; + using JobModel = Task::Job::ModelIO; }; class CullItemsTransparent { public: void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems); - typedef Job::ModelIO JobModel; + using JobModel = Task::Job::ModelIO; }; class DepthSortItems { @@ -265,14 +63,14 @@ public: void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outITems); - typedef Job::ModelIO JobModel; + using JobModel = Task::Job::ModelIO; }; class DrawLight { public: void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); - typedef Job::Model JobModel; + using JobModel = Task::Job::Model; }; 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 { @@ -313,4 +110,4 @@ void materialSortItems(const SceneContextPointer& sceneContext, const RenderCont } -#endif // hifi_render_Task_h +#endif // hifi_render_DrawTask_h diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index 907c836347..4f07da8d38 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -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()), _renderContext(std::make_shared()) @@ -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); } diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 4192dd3ed9..e07402f411 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -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; - -// 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 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 TaskPointer; -typedef std::vector 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 EnginePointer; } #endif // hifi_render_Engine_h + diff --git a/libraries/render/src/render/Task.h b/libraries/render/src/render/Task.h new file mode 100644 index 0000000000..66221d89e8 --- /dev/null +++ b/libraries/render/src/render/Task.h @@ -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 + +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 Varying(const T& data) : _concept(std::make_shared>(data)) {} + + template T& edit() { return std::static_pointer_cast>(_concept)->_data; } + template const T& get() { return std::static_pointer_cast>(_concept)->_data; } + +protected: + class Concept { + public: + virtual ~Concept() = default; + }; + template class Model : public Concept { + public: + using Data = T; + + Model(const Data& data) : _data(data) {} + virtual ~Model() = default; + + Data _data; + }; + + std::shared_ptr _concept; +}; + +// FIXME: In c++17, use default classes of nullptr_t to combine these +template void jobRun(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + jobModel.run(sceneContext, renderContext); +} +template void jobRunI(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const I& input) { + jobModel.run(sceneContext, renderContext, input); +} +template void jobRunO(T& jobModel, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, O& output) { + jobModel.run(sceneContext, renderContext, output); +} +template 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; + + + template 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 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()); + } + } + }; + + template 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()); + } + } + }; + + template 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(), _output.edit()); + } + } + }; + + 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 T& edit() { + auto concept = std::static_pointer_cast(_concept); + assert(concept); + return concept->_data; + } + template const T& get() const { + auto concept = std::static_pointer_cast(_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; + +public: + using VaryingPointer = std::shared_ptr; + + Task() {} + ~Task() {} + + // Queue a new job to the task; returns the job's index + template size_t addJob(std::string name, std::shared_ptr jobConcept) + { size_t size = _jobs.size(); _jobs.emplace_back(name, jobConcept); return size; } + template size_t addJob(std::shared_ptr 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 TaskPointer; +typedef std::vector Tasks; + +} + +#endif // hifi_render_Task_h