mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 16:55:06 +02:00
Merge pull request #13219 from samcake/one
Bringing Evolution to the Job Engine Task library developed in the workload project to master
This commit is contained in:
commit
04bf8f851f
21 changed files with 499 additions and 97 deletions
|
@ -649,7 +649,7 @@ private:
|
|||
quint64 _lastFaceTrackerUpdate;
|
||||
|
||||
render::ScenePointer _main3DScene{ new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) };
|
||||
render::EnginePointer _renderEngine{ new render::Engine() };
|
||||
render::EnginePointer _renderEngine{ new render::RenderEngine() };
|
||||
gpu::ContextPointer _gpuContext; // initialized during window creation
|
||||
|
||||
mutable QMutex _renderArgsMutex{ QMutex::Recursive };
|
||||
|
|
|
@ -181,7 +181,7 @@ class DebugAmbientOcclusionConfig : public render::Job::Config {
|
|||
Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
|
||||
Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
|
||||
public:
|
||||
DebugAmbientOcclusionConfig() : render::Job::Config(true) {}
|
||||
DebugAmbientOcclusionConfig() : render::Job::Config(false) {}
|
||||
|
||||
bool showCursorPixel{ false };
|
||||
glm::vec2 debugCursorTexcoord{ 0.5f, 0.5f };
|
||||
|
|
|
@ -195,7 +195,7 @@ class DebugLightClustersConfig : public render::Job::Config {
|
|||
Q_PROPERTY(bool doDrawClusterFromDepth MEMBER doDrawClusterFromDepth NOTIFY dirty)
|
||||
Q_PROPERTY(bool doDrawContent MEMBER doDrawContent NOTIFY dirty)
|
||||
public:
|
||||
DebugLightClustersConfig() : render::Job::Config(true){}
|
||||
DebugLightClustersConfig() : render::Job::Config(false){}
|
||||
|
||||
|
||||
bool doDrawGrid{ false };
|
||||
|
|
|
@ -149,7 +149,7 @@ class DebugSubsurfaceScatteringConfig : public render::Job::Config {
|
|||
Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
|
||||
Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
|
||||
public:
|
||||
DebugSubsurfaceScatteringConfig() : render::Job::Config(true) {}
|
||||
DebugSubsurfaceScatteringConfig() : render::Job::Config(false) {}
|
||||
|
||||
bool showProfile{ false };
|
||||
bool showLUT{ false };
|
||||
|
|
|
@ -36,12 +36,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
Engine::Engine() : Task(EngineTask::JobModel::create("Engine")),
|
||||
_renderContext(std::make_shared<RenderContext>())
|
||||
RenderEngine::RenderEngine() : Engine(EngineTask::JobModel::create("Engine"), std::make_shared<RenderContext>())
|
||||
{
|
||||
}
|
||||
|
||||
void Engine::load() {
|
||||
void RenderEngine::load() {
|
||||
auto config = getConfiguration();
|
||||
const QString configFile= "config/render.json";
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace render {
|
|||
|
||||
class RenderContext : public task::JobContext {
|
||||
public:
|
||||
RenderContext() : task::JobContext(trace_render()) {}
|
||||
RenderContext() : task::JobContext() {}
|
||||
virtual ~RenderContext() {}
|
||||
|
||||
RenderArgs* args;
|
||||
|
@ -33,7 +33,9 @@ namespace render {
|
|||
};
|
||||
using RenderContextPointer = std::shared_ptr<RenderContext>;
|
||||
|
||||
Task_DeclareTypeAliases(RenderContext)
|
||||
Task_DeclareCategoryTimeProfilerClass(RenderTimeProfiler, trace_render);
|
||||
|
||||
Task_DeclareTypeAliases(RenderContext, RenderTimeProfiler)
|
||||
|
||||
// Versions of the COnfig integrating a gpu & batch timer
|
||||
class GPUJobConfig : public JobConfig {
|
||||
|
@ -57,10 +59,10 @@ namespace render {
|
|||
|
||||
class GPUTaskConfig : public TaskConfig {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(double gpuRunTime READ getGPURunTime)
|
||||
Q_PROPERTY(double batchRunTime READ getBatchRunTime)
|
||||
Q_PROPERTY(double gpuRunTime READ getGPURunTime)
|
||||
Q_PROPERTY(double batchRunTime READ getBatchRunTime)
|
||||
|
||||
double _msGPURunTime { 0.0 };
|
||||
double _msGPURunTime { 0.0 };
|
||||
double _msBatchRunTime { 0.0 };
|
||||
public:
|
||||
|
||||
|
@ -80,32 +82,25 @@ namespace render {
|
|||
// The render engine holds all render tasks, and is itself a render task.
|
||||
// State flows through tasks to jobs via the render and scene contexts -
|
||||
// the engine should not be known from its jobs.
|
||||
class Engine : public Task {
|
||||
class RenderEngine : public Engine {
|
||||
public:
|
||||
|
||||
Engine();
|
||||
~Engine() = default;
|
||||
RenderEngine();
|
||||
~RenderEngine() = default;
|
||||
|
||||
// Load any persisted settings, and set up the presets
|
||||
// This should be run after adding all jobs, and before building ui
|
||||
void load();
|
||||
|
||||
// Register the scene
|
||||
void registerScene(const ScenePointer& scene) { _renderContext->_scene = scene; }
|
||||
void registerScene(const ScenePointer& scene) { _context->_scene = scene; }
|
||||
|
||||
// acces the RenderContext
|
||||
RenderContextPointer getRenderContext() const { return _renderContext; }
|
||||
|
||||
// Render a frame
|
||||
// Must have a scene registered and a context set
|
||||
void run() { assert(_renderContext); Task::run(_renderContext); }
|
||||
RenderContextPointer getRenderContext() const { return _context; }
|
||||
|
||||
protected:
|
||||
RenderContextPointer _renderContext;
|
||||
|
||||
void run(const RenderContextPointer& context) override { assert(_renderContext); Task::run(_renderContext); }
|
||||
};
|
||||
using EnginePointer = std::shared_ptr<Engine>;
|
||||
using EnginePointer = std::shared_ptr<RenderEngine>;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ public:
|
|||
Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); }
|
||||
Builder& withDeformed() { _flags.set(DEFORMED); return (*this); }
|
||||
Builder& withInvisible() { _flags.set(INVISIBLE); return (*this); }
|
||||
Builder& withVisible() { _flags.reset(INVISIBLE); return (*this); }
|
||||
Builder& withShadowCaster() { _flags.set(SHADOW_CASTER); return (*this); }
|
||||
Builder& withLayered() { _flags.set(LAYERED); return (*this); }
|
||||
Builder& withMetaCullGroup() { _flags.set(META_CULL_GROUP); return (*this); }
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace render {
|
||||
|
||||
class Engine;
|
||||
class RenderEngine;
|
||||
class Scene;
|
||||
|
||||
// Transaction is the mechanism to make any change to the scene.
|
||||
|
@ -236,7 +236,7 @@ protected:
|
|||
StageMap _stages;
|
||||
|
||||
|
||||
friend class Engine;
|
||||
friend class RenderEngine;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Scene> ScenePointer;
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#ifndef hifi_task_Config_h
|
||||
#define hifi_task_Config_h
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qjsondocument.h>
|
||||
#include <QtCore/qjsonobject.h>
|
||||
|
@ -117,11 +119,19 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE void load(const QVariantMap& map) { qObjectFromJsonValue(QJsonObject::fromVariantMap(map), *this); emit loaded(); }
|
||||
|
||||
Q_INVOKABLE QObject* getConfig(const QString& name) { return nullptr; }
|
||||
|
||||
// Running Time measurement
|
||||
// The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated
|
||||
void setCPURunTime(double mstime) { _msCPURunTime = mstime; emit newStats(); }
|
||||
void setCPURunTime(const std::chrono::nanoseconds& runtime) { _msCPURunTime = std::chrono::duration<double, std::milli>(runtime).count(); emit newStats(); }
|
||||
double getCPURunTime() const { return _msCPURunTime; }
|
||||
|
||||
// Describe the node graph data connections of the associated Job/Task
|
||||
Q_INVOKABLE virtual bool isTask() const { return false; }
|
||||
Q_INVOKABLE virtual QObjectList getSubConfigs() const { return QObjectList(); }
|
||||
Q_INVOKABLE virtual int getNumSubs() const { return 0; }
|
||||
Q_INVOKABLE virtual QObject* getSubConfig(int i) const { return nullptr; }
|
||||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
|
@ -151,6 +161,8 @@ signals:
|
|||
void dirtyEnabled();
|
||||
};
|
||||
|
||||
using QConfigPointer = std::shared_ptr<JobConfig>;
|
||||
|
||||
class TConfigProxy {
|
||||
public:
|
||||
using Config = JobConfig;
|
||||
|
@ -173,9 +185,10 @@ public:
|
|||
|
||||
using Persistent = PersistentConfig<TaskConfig>;
|
||||
|
||||
TaskConfig() = default ;
|
||||
TaskConfig() = default;
|
||||
TaskConfig(bool enabled) : JobConfig(enabled) {}
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @function Render.getConfig
|
||||
* @param {string} name
|
||||
|
@ -212,6 +225,21 @@ public:
|
|||
return root->findChild<typename T::Config*>(tokens.front());
|
||||
}
|
||||
|
||||
Q_INVOKABLE bool isTask() const override { return true; }
|
||||
Q_INVOKABLE QObjectList getSubConfigs() const override {
|
||||
auto list = findChildren<JobConfig*>(QRegExp(".*"), Qt::FindDirectChildrenOnly);
|
||||
QObjectList returned;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
returned.push_back(list[i]);
|
||||
}
|
||||
return returned;
|
||||
}
|
||||
Q_INVOKABLE int getNumSubs() const override { return getSubConfigs().size(); }
|
||||
Q_INVOKABLE QObject* getSubConfig(int i) const override {
|
||||
auto subs = getSubConfigs();
|
||||
return ((i < 0 || i >= subs.size()) ? nullptr : subs[i]);
|
||||
}
|
||||
|
||||
void connectChildConfig(QConfigPointer childConfig, const std::string& name);
|
||||
void transferChildrenConfigs(QConfigPointer source);
|
||||
|
||||
|
@ -225,8 +253,6 @@ public slots:
|
|||
void refresh();
|
||||
};
|
||||
|
||||
using QConfigPointer = std::shared_ptr<QObject>;
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_task_Config_h
|
||||
|
|
|
@ -12,9 +12,7 @@
|
|||
|
||||
using namespace task;
|
||||
|
||||
JobContext::JobContext(const QLoggingCategory& category) :
|
||||
profileCategory(category) {
|
||||
assert(&category);
|
||||
JobContext::JobContext() {
|
||||
}
|
||||
|
||||
JobContext::~JobContext() {
|
||||
|
|
|
@ -15,20 +15,15 @@
|
|||
#include "Config.h"
|
||||
#include "Varying.h"
|
||||
|
||||
#include "SettingHandle.h"
|
||||
|
||||
#include <Profile.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
namespace task {
|
||||
|
||||
class JobConcept;
|
||||
template <class JC> class JobT;
|
||||
template <class JC> class TaskT;
|
||||
template <class JC, class TP> class JobT;
|
||||
template <class JC, class TP> class TaskT;
|
||||
class JobNoIO {};
|
||||
|
||||
// Task Flow control class is a simple per value object used to communicate flow control commands trhough the graph of tasks.
|
||||
// From within the Job::Run function, you can access it from the JobCOntext and issue commands which will be picked up by the Task calling for the Job run.
|
||||
// From within the Job::Run function, you can access it from the JobContext and issue commands which will be picked up by the Task calling for the Job run.
|
||||
// This is first introduced to provide a way to abort all the work from within a task job. see the "abortTask" call
|
||||
class TaskFlow {
|
||||
public:
|
||||
|
@ -55,11 +50,10 @@ protected:
|
|||
// The JobContext can be derived to add more global state to it that Jobs can access
|
||||
class JobContext {
|
||||
public:
|
||||
JobContext(const QLoggingCategory& category);
|
||||
JobContext();
|
||||
virtual ~JobContext();
|
||||
|
||||
std::shared_ptr<JobConfig> jobConfig { nullptr };
|
||||
const QLoggingCategory& profileCategory;
|
||||
|
||||
// Task flow control
|
||||
TaskFlow taskFlow{};
|
||||
|
@ -80,10 +74,11 @@ public:
|
|||
|
||||
virtual const Varying getInput() const { return Varying(); }
|
||||
virtual const Varying getOutput() const { return Varying(); }
|
||||
virtual Varying& editInput() = 0;
|
||||
|
||||
virtual QConfigPointer& getConfiguration() { return _config; }
|
||||
virtual void applyConfiguration() = 0;
|
||||
void setCPURunTime(double mstime) { std::static_pointer_cast<Config>(_config)->setCPURunTime(mstime); }
|
||||
void setCPURunTime(const std::chrono::nanoseconds& runtime) { std::static_pointer_cast<Config>(_config)->setCPURunTime(runtime); }
|
||||
|
||||
QConfigPointer _config;
|
||||
protected:
|
||||
|
@ -114,10 +109,11 @@ template <class T, class JC, class I, class O> void jobRun(T& data, const JC& jo
|
|||
data.run(jobContext, input, output);
|
||||
}
|
||||
|
||||
template <class JC>
|
||||
template <class JC, class TP>
|
||||
class Job {
|
||||
public:
|
||||
using Context = JC;
|
||||
using TimeProfiler = TP;
|
||||
using ContextPointer = std::shared_ptr<Context>;
|
||||
using Config = JobConfig;
|
||||
using None = JobNoIO;
|
||||
|
@ -143,6 +139,7 @@ public:
|
|||
|
||||
const Varying getInput() const override { return _input; }
|
||||
const Varying getOutput() const override { return _output; }
|
||||
Varying& editInput() override { return _input; }
|
||||
|
||||
template <class... A>
|
||||
Model(const std::string& name, const Varying& input, QConfigPointer config, A&&... args) :
|
||||
|
@ -160,7 +157,7 @@ public:
|
|||
|
||||
|
||||
void applyConfiguration() override {
|
||||
Duration profileRange(trace_render(), ("configure::" + JobConcept::getName()).c_str());
|
||||
TimeProfiler probe(("configure::" + JobConcept::getName()));
|
||||
|
||||
jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config));
|
||||
}
|
||||
|
@ -185,6 +182,9 @@ public:
|
|||
QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); }
|
||||
void applyConfiguration() { return _concept->applyConfiguration(); }
|
||||
|
||||
template <class I> void feedInput(const I& in) { _concept->editInput().template edit<I>() = in; }
|
||||
template <class I, class S> void feedInput(int index, const S& inS) { (_concept->editInput().template editN<I>(index)).template edit<S>() = inS; }
|
||||
|
||||
template <class T> T& edit() {
|
||||
auto concept = std::static_pointer_cast<typename T::JobModel>(_concept);
|
||||
assert(concept);
|
||||
|
@ -198,14 +198,10 @@ public:
|
|||
}
|
||||
|
||||
virtual void run(const ContextPointer& jobContext) {
|
||||
PerformanceTimer perfTimer(getName().c_str());
|
||||
// NOTE: rather than use the PROFILE_RANGE macro, we create a Duration manually
|
||||
Duration profileRange(jobContext->profileCategory, ("run::" + getName()).c_str());
|
||||
auto start = usecTimestampNow();
|
||||
|
||||
TimeProfiler probe(getName());
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
_concept->run(jobContext);
|
||||
|
||||
_concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0);
|
||||
_concept->setCPURunTime((std::chrono::high_resolution_clock::now() - startTime));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -220,13 +216,14 @@ protected:
|
|||
// The build method is where child Jobs can be added internally to the task
|
||||
// where the input of the task can be setup to feed the child jobs
|
||||
// and where the output of the task is defined
|
||||
template <class JC>
|
||||
class Task : public Job<JC> {
|
||||
template <class JC, class TP>
|
||||
class Task : public Job<JC, TP> {
|
||||
public:
|
||||
using Context = JC;
|
||||
using TimeProfiler = TP;
|
||||
using ContextPointer = std::shared_ptr<Context>;
|
||||
using Config = TaskConfig;
|
||||
using JobType = Job<JC>;
|
||||
using JobType = Job<JC, TP>;
|
||||
using None = typename JobType::None;
|
||||
using Concept = typename JobType::Concept;
|
||||
using ConceptPointer = typename JobType::ConceptPointer;
|
||||
|
@ -242,6 +239,8 @@ public:
|
|||
|
||||
const Varying getInput() const override { return _input; }
|
||||
const Varying getOutput() const override { return _output; }
|
||||
Varying& editInput() override { return _input; }
|
||||
|
||||
typename Jobs::iterator editJob(std::string name) {
|
||||
typename Jobs::iterator jobIt;
|
||||
for (jobIt = _jobs.begin(); jobIt != _jobs.end(); ++jobIt) {
|
||||
|
@ -295,7 +294,7 @@ public:
|
|||
auto model = std::make_shared<TaskModel>(name, input, std::make_shared<C>());
|
||||
|
||||
{
|
||||
Duration profileRange(trace_render(), ("build::" + model->getName()).c_str());
|
||||
TimeProfiler probe("build::" + model->getName());
|
||||
model->_data.build(*(model), model->_input, model->_output, std::forward<A>(args)...);
|
||||
}
|
||||
// Recreate the Config to use the templated type
|
||||
|
@ -330,7 +329,7 @@ public:
|
|||
}
|
||||
|
||||
void applyConfiguration() override {
|
||||
Duration profileRange(trace_render(), ("configure::" + JobConcept::getName()).c_str());
|
||||
TimeProfiler probe("configure::" + JobConcept::getName());
|
||||
jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config));
|
||||
for (auto& job : TaskConcept::_jobs) {
|
||||
job.applyConfiguration();
|
||||
|
@ -370,15 +369,44 @@ public:
|
|||
|
||||
protected:
|
||||
};
|
||||
|
||||
template <class JC, class TP>
|
||||
class Engine : public Task<JC, TP> {
|
||||
public:
|
||||
using Context = JC;
|
||||
using ContextPointer = std::shared_ptr<Context>;
|
||||
using Config = TaskConfig;
|
||||
using TaskType = Task<JC, TP>;
|
||||
using ConceptPointer = typename TaskType::ConceptPointer;
|
||||
|
||||
Engine(const ConceptPointer& concept, const ContextPointer& context) : TaskType(concept), _context(context) {}
|
||||
~Engine() = default;
|
||||
|
||||
void reset(const ContextPointer& context) { _context = context; }
|
||||
|
||||
void run() {
|
||||
if (_context) {
|
||||
run(_context);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void run(const ContextPointer& jobContext) override {
|
||||
TaskType::run(_context);
|
||||
}
|
||||
|
||||
ContextPointer _context;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define Task_DeclareTypeAliases(ContextType) \
|
||||
#define Task_DeclareTypeAliases(ContextType, TimeProfiler) \
|
||||
using JobConfig = task::JobConfig; \
|
||||
using TaskConfig = task::TaskConfig; \
|
||||
template <class T> using PersistentConfig = task::PersistentConfig<T>; \
|
||||
using Job = task::Job<ContextType>; \
|
||||
using Task = task::Task<ContextType>; \
|
||||
using Job = task::Job<ContextType, TimeProfiler>; \
|
||||
using Task = task::Task<ContextType, TimeProfiler>; \
|
||||
using Engine = task::Engine<ContextType, TimeProfiler>; \
|
||||
using Varying = task::Varying; \
|
||||
template < typename T0, typename T1 > using VaryingSet2 = task::VaryingSet2<T0, T1>; \
|
||||
template < typename T0, typename T1, typename T2 > using VaryingSet3 = task::VaryingSet3<T0, T1, T2>; \
|
||||
|
@ -389,4 +417,16 @@ protected:
|
|||
template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 > using VaryingSet8 = task::VaryingSet8<T0, T1, T2, T3, T4, T5, T6, T7>; \
|
||||
template < class T, int NUM > using VaryingArray = task::VaryingArray<T, NUM>;
|
||||
|
||||
|
||||
|
||||
#include <Profile.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
#define Task_DeclareCategoryTimeProfilerClass(className, category) \
|
||||
class className : public PerformanceTimer { \
|
||||
public: \
|
||||
className(const std::string& label) : PerformanceTimer(label.c_str()), profileRange(category(), label.c_str()) {} \
|
||||
Duration profileRange; \
|
||||
};
|
||||
|
||||
#endif // hifi_task_Task_h
|
||||
|
|
82
scripts/developer/utilities/lib/jet/jet.js
Normal file
82
scripts/developer/utilities/lib/jet/jet.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// Job Engine & Task...
|
||||
// jet.js
|
||||
//
|
||||
// Created by Sam Gateau, 2018/03/28
|
||||
// Copyright 2018 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
|
||||
//
|
||||
"use strict";
|
||||
|
||||
// traverse task tree
|
||||
function task_traverse(root, functor, depth) {
|
||||
if (root.isTask()) {
|
||||
depth++;
|
||||
for (var i = 0; i <root.getNumSubs(); i++) {
|
||||
var sub = root.getSubConfig(i);
|
||||
if (functor(sub, depth, i)) {
|
||||
task_traverse(sub, functor, depth, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function task_traverseTree(root, functor) {
|
||||
if (functor(root, 0, 0)) {
|
||||
task_traverse(root, functor, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// Access job properties
|
||||
// return all the properties of a job
|
||||
function job_propKeys(job) {
|
||||
var keys = Object.keys(job)
|
||||
var propKeys = [];
|
||||
for (var k=0; k < keys.length;k++) {
|
||||
// Filter for relevant property
|
||||
var key = keys[k]
|
||||
if ((typeof job[key]) !== "function") {
|
||||
if ((key !== "objectName") && (key !== "cpuRunTime") && (key !== "enabled")) {
|
||||
propKeys.push(keys[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return propKeys;
|
||||
}
|
||||
|
||||
// Use this function to create a functor that will fill the specifed array with one entry name per task and job and it s rank
|
||||
function job_list_functor(jobList, maxDepth) {
|
||||
if (maxDepth === undefined) maxDepth = 100
|
||||
return function (job, depth, index) {
|
||||
jobList.push(job.objectName);
|
||||
return depth < maxDepth;
|
||||
}
|
||||
}
|
||||
|
||||
// Use this function to create a functor that will print the content of the Job visited calling the specified 'printout' function
|
||||
function job_print_functor(printout, showProps, maxDepth) {
|
||||
if (maxDepth === undefined) maxDepth = 100
|
||||
return function (job, depth, index) {
|
||||
var tab = " "
|
||||
var depthTab = "";
|
||||
for (var d = 0; d < depth; d++) { depthTab += tab }
|
||||
printout(depthTab + index + " " + job.objectName + " " + (job.enabled ? "on " : "off ") + job.cpuRunTime + "ms")
|
||||
if (showProps) {
|
||||
var keys = job_propKeys(job);
|
||||
for (var p=0; p < keys.length;p++) {
|
||||
var prop = job[keys[p]]
|
||||
printout(depthTab + tab + tab + typeof prop + " " + keys[p] + " " + prop);
|
||||
}
|
||||
}
|
||||
return depth < maxDepth;
|
||||
}
|
||||
}
|
||||
|
||||
// Expose functions for regular js including this files through the 'Jet' object
|
||||
/*Jet = {}
|
||||
Jet.task_traverse = task_traverse
|
||||
Jet.task_traverseTree = task_traverseTree
|
||||
Jet.job_propKeys = job_propKeys
|
||||
Jet.job_print_functor = job_print_functor
|
||||
*/
|
45
scripts/developer/utilities/lib/jet/qml/TaskList.qml
Normal file
45
scripts/developer/utilities/lib/jet/qml/TaskList.qml
Normal file
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// jet/TaskList.qml
|
||||
//
|
||||
// Created by Sam Gateau, 2018/03/28
|
||||
// Copyright 2018 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
|
||||
//
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4 as Original
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import "qrc:///qml/styles-uit"
|
||||
import "qrc:///qml/controls-uit" as HifiControls
|
||||
|
||||
import "../jet.js" as Jet
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi;}
|
||||
color: hifi.colors.baseGray;
|
||||
id: root
|
||||
// width: parent ? parent.width : 200
|
||||
// height: parent ? parent.height : 400
|
||||
property var rootConfig : Workload
|
||||
|
||||
Original.TextArea {
|
||||
id: textArea
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
text: ""
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
var message = ""
|
||||
var functor = Jet.job_print_functor(function (line) { message += line + "\n"; }, false);
|
||||
Jet.task_traverseTree(rootConfig, functor);
|
||||
textArea.append(message);
|
||||
}
|
||||
|
||||
function clearWindow() {
|
||||
textArea.remove(0,textArea.length);
|
||||
}
|
||||
}
|
119
scripts/developer/utilities/lib/jet/qml/TaskListView.qml
Normal file
119
scripts/developer/utilities/lib/jet/qml/TaskListView.qml
Normal file
|
@ -0,0 +1,119 @@
|
|||
//
|
||||
// jet/TaskListView.qml
|
||||
//
|
||||
// Created by Sam Gateau, 2018/05/09
|
||||
// Copyright 2018 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
|
||||
//
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4 as Original
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import "qrc:///qml/styles-uit"
|
||||
import "qrc:///qml/controls-uit" as HifiControls
|
||||
|
||||
import "../jet.js" as Jet
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi;}
|
||||
color: hifi.colors.baseGray;
|
||||
id: root;
|
||||
|
||||
property var rootConfig : Workload
|
||||
property var myArray : []
|
||||
|
||||
Component.onCompleted: {
|
||||
var message = ""
|
||||
var maxDepth = 3;
|
||||
|
||||
var jobTreePath = []
|
||||
var jobsRoot;
|
||||
|
||||
var functor = function (job, depth, index) {
|
||||
var newItem = {"name": job.objectName, "level": depth, "index": index, "subNode": [], "init": depth < maxDepth, "path": ""}
|
||||
if (depth == 0) {
|
||||
jobsModel.append(newItem)
|
||||
jobsRoot = jobsModel.get(0).subNode;
|
||||
} else {
|
||||
if (jobTreePath.length < depth) {
|
||||
var node = jobsRoot;
|
||||
var path;
|
||||
for (var n = 0; n < jobTreePath.length; n++) {
|
||||
newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name
|
||||
node = node.get(jobTreePath[n]).subNode
|
||||
}
|
||||
node.append(newItem)
|
||||
jobTreePath.push(0);
|
||||
} else if (jobTreePath.length >= depth) {
|
||||
var node = jobsRoot;
|
||||
for (var n = 0; n < (depth - 1); n++) {
|
||||
newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name
|
||||
node = node.get(jobTreePath[n]).subNode
|
||||
}
|
||||
node.append(newItem)
|
||||
jobTreePath[depth-1] = index;
|
||||
while (jobTreePath.length > depth) {
|
||||
jobTreePath.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Jet.task_traverseTree(rootConfig, functor);
|
||||
}
|
||||
|
||||
|
||||
ListModel {
|
||||
id: jobsModel
|
||||
}
|
||||
|
||||
Component {
|
||||
id: objRecursiveDelegate
|
||||
Column {
|
||||
id: objRecursiveColumn
|
||||
clip: true
|
||||
visible: model.init
|
||||
|
||||
MouseArea {
|
||||
width: objRow.implicitWidth
|
||||
height: objRow.implicitHeight
|
||||
onDoubleClicked: {
|
||||
for(var i = 1; i < parent.children.length - 1; ++i) {
|
||||
parent.children[i].visible = !parent.children[i].visible
|
||||
}
|
||||
}
|
||||
Row {
|
||||
id: objRow
|
||||
Item {
|
||||
height: 1
|
||||
width: model.level * 15
|
||||
}
|
||||
HifiControls.CheckBox {
|
||||
property var config: root.rootConfig.getConfig(model.path + "." + model.name);
|
||||
text: (objRecursiveColumn.children.length > 2 ?
|
||||
objRecursiveColumn.children[1].visible ?
|
||||
qsTr("- ") : qsTr("+ ") : qsTr(" ")) + model.name + " ms=" + config.cpuRunTime.toFixed(2)
|
||||
checked: config.enabled
|
||||
}
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
model: subNode
|
||||
delegate: objRecursiveDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Original.ScrollView {
|
||||
anchors.fill: parent
|
||||
ListView {
|
||||
id: theView
|
||||
model: jobsModel
|
||||
delegate: objRecursiveDelegate
|
||||
}
|
||||
}
|
||||
}
|
2
scripts/developer/utilities/lib/jet/qml/qmldir
Normal file
2
scripts/developer/utilities/lib/jet/qml/qmldir
Normal file
|
@ -0,0 +1,2 @@
|
|||
TaskList 1.0 TaskList.qml
|
||||
TaskViewList 1.0 TaskViewList.qml
|
|
@ -23,13 +23,22 @@ Item {
|
|||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: 24
|
||||
|
||||
property var labelAreaWidthScale: 0.5
|
||||
|
||||
property bool integral: false
|
||||
property var config
|
||||
property string property
|
||||
property alias label: labelControl.text
|
||||
property alias min: sliderControl.minimumValue
|
||||
property alias max: sliderControl.maximumValue
|
||||
|
||||
property alias label: labelControl.text
|
||||
property bool showLabel: true
|
||||
|
||||
property bool showValue: true
|
||||
|
||||
|
||||
|
||||
signal valueChanged(real value)
|
||||
|
||||
Component.onCompleted: {
|
||||
|
@ -41,20 +50,12 @@ Item {
|
|||
HifiControls.Label {
|
||||
id: labelControl
|
||||
text: root.label
|
||||
enabled: true
|
||||
enabled: root.showLabel
|
||||
anchors.left: root.left
|
||||
anchors.right: root.horizontalCenter
|
||||
width: root.width * root.labelAreaWidthScale
|
||||
anchors.verticalCenter: root.verticalCenter
|
||||
}
|
||||
|
||||
HifiControls.Label {
|
||||
id: labelValue
|
||||
text: sliderControl.value.toFixed(root.integral ? 0 : 2)
|
||||
anchors.right: root.right
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: 0
|
||||
}
|
||||
|
||||
|
||||
Binding {
|
||||
id: bindingControl
|
||||
target: root.config
|
||||
|
@ -66,7 +67,7 @@ Item {
|
|||
HifiControls.Slider {
|
||||
id: sliderControl
|
||||
stepSize: root.integral ? 1.0 : 0.0
|
||||
anchors.left: root.horizontalCenter
|
||||
anchors.left: labelControl.right
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 0
|
||||
anchors.top: root.top
|
||||
|
@ -74,4 +75,17 @@ Item {
|
|||
|
||||
onValueChanged: { root.valueChanged(value) }
|
||||
}
|
||||
|
||||
HifiControls.Label {
|
||||
id: labelValue
|
||||
enabled: root.showValue
|
||||
text: sliderControl.value.toFixed(root.integral ? 0 : 2)
|
||||
anchors.right: labelControl.right
|
||||
anchors.rightMargin: 5
|
||||
anchors.verticalCenter: root.verticalCenter
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -36,9 +36,9 @@ Rectangle {
|
|||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
spacing: 20
|
||||
spacing: 5
|
||||
Column {
|
||||
spacing: 10
|
||||
spacing: 5
|
||||
// padding: 10
|
||||
Repeater {
|
||||
model: [
|
||||
|
@ -61,7 +61,7 @@ Rectangle {
|
|||
|
||||
|
||||
Column {
|
||||
spacing: 10
|
||||
spacing: 5
|
||||
Repeater {
|
||||
model: [
|
||||
"Obscurance:LightingModel:enableObscurance",
|
||||
|
@ -81,7 +81,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
Column {
|
||||
spacing: 10
|
||||
spacing: 5
|
||||
Repeater {
|
||||
model: [
|
||||
"Ambient:LightingModel:enableAmbientLight",
|
||||
|
@ -105,7 +105,7 @@ Rectangle {
|
|||
Column {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: 10
|
||||
spacing: 5
|
||||
Repeater {
|
||||
model: [ "Tone Mapping Exposure:ToneMapping:exposure:5.0:-5.0"
|
||||
]
|
||||
|
@ -211,9 +211,9 @@ Rectangle {
|
|||
|
||||
Separator {}
|
||||
Row {
|
||||
spacing: 10
|
||||
spacing: 5
|
||||
Column {
|
||||
spacing: 10
|
||||
spacing: 5
|
||||
|
||||
HifiControls.CheckBox {
|
||||
boxSize: 20
|
||||
|
@ -254,7 +254,7 @@ Rectangle {
|
|||
|
||||
}
|
||||
Column {
|
||||
spacing: 10
|
||||
spacing: 5
|
||||
HifiControls.CheckBox {
|
||||
boxSize: 20
|
||||
text: "Metas"
|
||||
|
@ -275,6 +275,13 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
Separator {}
|
||||
HifiControls.Button {
|
||||
text: "Engine"
|
||||
// activeFocusOnPress: false
|
||||
onClicked: {
|
||||
sendToScript({method: "openEngineView"});
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
|
13
scripts/developer/utilities/render/engineInspector.js
Normal file
13
scripts/developer/utilities/render/engineInspector.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
function openEngineTaskView() {
|
||||
// Set up the qml ui
|
||||
var qml = Script.resolvePath('engineInspector.qml');
|
||||
var window = new OverlayWindow({
|
||||
title: 'Render Engine',
|
||||
source: qml,
|
||||
width: 300,
|
||||
height: 400
|
||||
});
|
||||
window.setPosition(200, 50);
|
||||
//window.closed.connect(function() { Script.stop(); });
|
||||
}
|
||||
openEngineTaskView();
|
30
scripts/developer/utilities/render/engineInspector.qml
Normal file
30
scripts/developer/utilities/render/engineInspector.qml
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// deferredLighting.qml
|
||||
//
|
||||
// Created by Sam Gateau on 6/6/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import "qrc:///qml/styles-uit"
|
||||
import "qrc:///qml/controls-uit" as HifiControls
|
||||
|
||||
import "../lib/jet/qml" as Jet
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi;}
|
||||
id: render;
|
||||
anchors.fill: parent
|
||||
|
||||
property var mainViewTask: Render.getConfig("RenderMainView")
|
||||
|
||||
Jet.TaskListView {
|
||||
rootConfig: Render
|
||||
anchors.fill: render
|
||||
}
|
||||
}
|
|
@ -64,9 +64,6 @@
|
|||
button.editProperties({isActive: onLuciScreen});
|
||||
wireEventBridge(onLuciScreen);
|
||||
}
|
||||
|
||||
function fromQml(message) {
|
||||
}
|
||||
|
||||
button.clicked.connect(onClicked);
|
||||
tablet.screenChanged.connect(onScreenChanged);
|
||||
|
@ -82,14 +79,6 @@
|
|||
Controller.mouseMoveEvent.connect(function (e) { if (moveDebugCursor) setDebugCursor(e.x, e.y); });
|
||||
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onLuciScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
button.clicked.disconnect(onClicked);
|
||||
tablet.screenChanged.disconnect(onScreenChanged);
|
||||
tablet.removeButton(button);
|
||||
});
|
||||
|
||||
function setDebugCursor(x, y) {
|
||||
nx = (x / Window.innerWidth);
|
||||
|
@ -98,4 +87,46 @@
|
|||
Render.getConfig("RenderMainView").getConfig("Antialiasing").debugCursorTexcoord = { x: nx, y: ny };
|
||||
}
|
||||
|
||||
|
||||
function fromQml(message) {
|
||||
switch (message.method) {
|
||||
case "openEngineView":
|
||||
openEngineTaskView();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var engineInspectorView = null
|
||||
function openEngineTaskView() {
|
||||
if (engineInspectorView == null) {
|
||||
var qml = Script.resolvePath('engineInspector.qml');
|
||||
var window = new OverlayWindow({
|
||||
title: 'Render Engine',
|
||||
source: qml,
|
||||
width: 300,
|
||||
height: 400
|
||||
});
|
||||
window.setPosition(200, 50);
|
||||
engineInspectorView = window
|
||||
window.closed.connect(function() { engineInspectorView = null; });
|
||||
} else {
|
||||
engineInspectorView.setPosition(200, 50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onLuciScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
button.clicked.disconnect(onClicked);
|
||||
tablet.screenChanged.disconnect(onScreenChanged);
|
||||
tablet.removeButton(button);
|
||||
|
||||
if (engineInspectorView !== null) {
|
||||
engineInspectorView.close()
|
||||
}
|
||||
});
|
||||
}());
|
|
@ -1107,7 +1107,7 @@ private:
|
|||
}
|
||||
} };
|
||||
|
||||
render::EnginePointer _renderEngine { new render::Engine() };
|
||||
render::EnginePointer _renderEngine { new render::RenderEngine() };
|
||||
render::ScenePointer _main3DScene { new render::Scene(glm::vec3(-0.5f * (float)TREE_SCALE), (float)TREE_SCALE) };
|
||||
QSize _size;
|
||||
QSettings _settings;
|
||||
|
|
Loading…
Reference in a new issue