Improvements to profiling data capture

Use code-provided task names for profile blocks; record QML URLs for
loadInternal.
This commit is contained in:
Simon Walton 2018-04-11 17:36:32 -07:00
parent ca5720c015
commit adcf991125
13 changed files with 33 additions and 37 deletions

View file

@ -129,7 +129,7 @@ void Context::executeFrame(const FramePointer& frame) const {
} }
bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings, const Shader::CompilationHandler& handler) { bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings, const Shader::CompilationHandler& handler) {
PROFILE_RANGE(app, "makeProgram"); PROFILE_RANGE_EX(app, "makeProgram", 0xff4040c0, shader.getID());
// If we're running in another DLL context, we need to fetch the program callback out of the application // If we're running in another DLL context, we need to fetch the program callback out of the application
// FIXME find a way to do this without reliance on Qt app properties // FIXME find a way to do this without reliance on Qt app properties
if (!_makeProgramCallback) { if (!_makeProgramCallback) {

View file

@ -286,7 +286,7 @@ void OffscreenSurface::loadInternal(const QUrl& qmlSource,
bool createNewContext, bool createNewContext,
QQuickItem* parent, QQuickItem* parent,
const QmlContextObjectCallback& callback) { const QmlContextObjectCallback& callback) {
PROFILE_RANGE(app, "loadInternal"); PROFILE_RANGE_EX(app, "OffscreenSurface::loadInternal", 0xffff00ff, 0, { std::make_pair("url", qmlSource.toDisplayString()) });
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
qFatal("Called load on a non-surface thread"); qFatal("Called load on a non-surface thread");
} }

View file

@ -326,7 +326,6 @@ Bloom::Bloom() {
} }
void Bloom::configure(const Config& config) { void Bloom::configure(const Config& config) {
PROFILE_RANGE(startup, "Bloom::build");
std::string blurName{ "BloomBlurN" }; std::string blurName{ "BloomBlurN" };
for (auto i = 0; i < BLOOM_BLUR_LEVEL_COUNT; i++) { for (auto i = 0; i < BLOOM_BLUR_LEVEL_COUNT; i++) {

View file

@ -476,7 +476,6 @@ void DrawHighlightTask::configure(const Config& config) {
} }
void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs) { void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs) {
PROFILE_RANGE(startup, "Bloom::build");
const auto items = inputs.getN<Inputs>(0).get<RenderFetchCullSortTask::BucketList>(); const auto items = inputs.getN<Inputs>(0).get<RenderFetchCullSortTask::BucketList>();
const auto sceneFrameBuffer = inputs.getN<Inputs>(1); const auto sceneFrameBuffer = inputs.getN<Inputs>(1);
const auto primaryFramebuffer = inputs.getN<Inputs>(2); const auto primaryFramebuffer = inputs.getN<Inputs>(2);

View file

@ -76,7 +76,6 @@ const render::Varying RenderDeferredTask::addSelectItemJobs(JobModel& task, cons
} }
void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
PROFILE_RANGE(startup, "RenderDeferredTask::build");
const auto& items = input.get<Input>(); const auto& items = input.get<Input>();
auto fadeEffect = DependencyManager::get<FadeEffect>(); auto fadeEffect = DependencyManager::get<FadeEffect>();

View file

@ -40,7 +40,6 @@ extern void initForwardPipelines(ShapePlumber& plumber,
extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false); extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false);
void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
PROFILE_RANGE(startup, "RenderForwardTask::build");
auto items = input.get<Input>(); auto items = input.get<Input>();
auto fadeEffect = DependencyManager::get<FadeEffect>(); auto fadeEffect = DependencyManager::get<FadeEffect>();

View file

@ -215,7 +215,6 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con
void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) { void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) {
::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& bounds) { ::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& bounds) {
PROFILE_RANGE(startup, "RenderShadowTask::build");
return _cullFunctor(args, bounds); return _cullFunctor(args, bounds);
}; };

View file

@ -17,7 +17,6 @@
void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t tagBits, uint8_t tagMask) { void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t tagBits, uint8_t tagMask) {
// auto items = input.get<Input>(); // auto items = input.get<Input>();
PROFILE_RANGE(startup, "RenderViewTask::build");
// Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling // Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling
// is performed, then casters not in the view frustum will be removed, which is not what we wish. // is performed, then casters not in the view frustum will be removed, which is not what we wish.
task.addJob<RenderShadowTask>("RenderShadowTask", cullFunctor, tagBits, tagMask); task.addJob<RenderShadowTask>("RenderShadowTask", cullFunctor, tagBits, tagMask);

View file

@ -19,7 +19,6 @@
#include "DeferredLightingEffect.h" #include "DeferredLightingEffect.h"
void UpdateSceneTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { void UpdateSceneTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
PROFILE_RANGE(startup, "UpdateSceneTask::build");
task.addJob<LightStageSetup>("LightStageSetup"); task.addJob<LightStageSetup>("LightStageSetup");
task.addJob<BackgroundStageSetup>("BackgroundStageSetup"); task.addJob<BackgroundStageSetup>("BackgroundStageSetup");
task.addJob<HazeStageSetup>("HazeStageSetup"); task.addJob<HazeStageSetup>("HazeStageSetup");

View file

@ -42,7 +42,6 @@ protected:
const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" };
void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) { void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) {
PROFILE_RANGE(startup, "ZoneRendererTask::build");
// Filter out the sorted list of zones // Filter out the sorted list of zones
const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION.c_str()); const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION.c_str());

View file

@ -36,7 +36,7 @@ public:
} }
}; };
Engine::Engine() : Task("Engine", EngineTask::JobModel::create()), Engine::Engine() : Task(EngineTask::JobModel::create("Engine")),
_renderContext(std::make_shared<RenderContext>()) _renderContext(std::make_shared<RenderContext>())
{ {
} }

View file

@ -20,7 +20,6 @@ using namespace render;
void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varying& output, CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) { void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varying& output, CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) {
cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; };
PROFILE_RANGE(startup, "RenderFetchCullSortTask::build");
// CPU jobs: // CPU jobs:
// Fetch and cull the items from the scene // Fetch and cull the items from the scene
const ItemFilter filter = ItemFilter::Builder::visibleWorldItems().withoutLayered().withTagBits(tagBits, tagMask); const ItemFilter filter = ItemFilter::Builder::visibleWorldItems().withoutLayered().withTagBits(tagBits, tagMask);

View file

@ -47,7 +47,7 @@ protected:
bool _doAbortTask{ false }; bool _doAbortTask{ false };
}; };
// JobContext class is the base calss for the context object which is passed through all the Job::run calls thoughout the graph of jobs // JobContext class is the base class for the context object which is passed through all the Job::run calls thoughout the graph of jobs
// It is used to communicate to the job::run its context and various state information the job relies on. // It is used to communicate to the job::run its context and various state information the job relies on.
// It specifically provide access to: // It specifically provide access to:
// - The taskFlow object allowing for messaging control flow commands from within a Job::run // - The taskFlow object allowing for messaging control flow commands from within a Job::run
@ -73,19 +73,21 @@ class JobConcept {
public: public:
using Config = JobConfig; using Config = JobConfig;
JobConcept(QConfigPointer config) : _config(config) {} JobConcept(const std::string& name, QConfigPointer config) : _name(name), _config(config) {}
virtual ~JobConcept() = default; virtual ~JobConcept() = default;
const std::string& getName() const { return _name; }
virtual const Varying getInput() const { return Varying(); } virtual const Varying getInput() const { return Varying(); }
virtual const Varying getOutput() const { return Varying(); } virtual const Varying getOutput() const { return Varying(); }
virtual QConfigPointer& getConfiguration() { return _config; } virtual QConfigPointer& getConfiguration() { return _config; }
virtual void applyConfiguration() = 0; virtual void applyConfiguration() = 0;
void setCPURunTime(double mstime) { std::static_pointer_cast<Config>(_config)->setCPURunTime(mstime); } void setCPURunTime(double mstime) { std::static_pointer_cast<Config>(_config)->setCPURunTime(mstime); }
QConfigPointer _config; QConfigPointer _config;
protected: protected:
const std::string _name;
}; };
@ -122,7 +124,7 @@ public:
class Concept : public JobConcept { class Concept : public JobConcept {
public: public:
Concept(QConfigPointer config) : JobConcept(config) {} Concept(const std::string& name, QConfigPointer config) : JobConcept(name, config) {}
virtual ~Concept() = default; virtual ~Concept() = default;
virtual void run(const ContextPointer& jobContext) = 0; virtual void run(const ContextPointer& jobContext) = 0;
@ -143,8 +145,8 @@ public:
const Varying getOutput() const override { return _output; } const Varying getOutput() const override { return _output; }
template <class... A> template <class... A>
Model(const Varying& input, QConfigPointer config, A&&... args) : Model(const std::string& name, const Varying& input, QConfigPointer config, A&&... args) :
Concept(config), Concept(name, config),
_data(Data(std::forward<A>(args)...)), _data(Data(std::forward<A>(args)...)),
_input(input), _input(input),
_output(Output()) { _output(Output()) {
@ -152,12 +154,14 @@ public:
} }
template <class... A> template <class... A>
static std::shared_ptr<Model> create(const Varying& input, A&&... args) { static std::shared_ptr<Model> create(const std::string& name, const Varying& input, A&&... args) {
return std::make_shared<Model>(input, std::make_shared<C>(), std::forward<A>(args)...); return std::make_shared<Model>(name, input, std::make_shared<C>(), std::forward<A>(args)...);
} }
void applyConfiguration() override { void applyConfiguration() override {
Duration profileRange(trace_render(), ("configure::" + getName()).c_str());
jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config)); jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config));
} }
@ -173,8 +177,9 @@ public:
template <class T, class O, class C = Config> using ModelO = Model<T, C, None, O>; template <class T, class O, class C = Config> using ModelO = Model<T, C, None, O>;
template <class T, class I, class O, class C = Config> using ModelIO = Model<T, C, I, O>; template <class T, class I, class O, class C = Config> using ModelIO = Model<T, C, I, O>;
Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {} Job(ConceptPointer concept) : _concept(concept) {}
const std::string& getName() const { return _concept->getName(); }
const Varying getInput() const { return _concept->getInput(); } const Varying getInput() const { return _concept->getInput(); }
const Varying getOutput() const { return _concept->getOutput(); } const Varying getOutput() const { return _concept->getOutput(); }
QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); } QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); }
@ -193,9 +198,9 @@ public:
} }
virtual void run(const ContextPointer& jobContext) { virtual void run(const ContextPointer& jobContext) {
PerformanceTimer perfTimer(_name.c_str()); PerformanceTimer perfTimer(getName().c_str());
// NOTE: rather than use the PROFILE_RANGE macro, we create a Duration manually // NOTE: rather than use the PROFILE_RANGE macro, we create a Duration manually
Duration profileRange(jobContext->profileCategory, _name.c_str()); Duration profileRange(jobContext->profileCategory, ("run::" + getName()).c_str());
auto start = usecTimestampNow(); auto start = usecTimestampNow();
_concept->run(jobContext); _concept->run(jobContext);
@ -203,11 +208,8 @@ public:
_concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0); _concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0);
} }
const std::string& getName() const { return _name; }
protected: protected:
ConceptPointer _concept; ConceptPointer _concept;
std::string _name = "";
}; };
@ -230,7 +232,7 @@ public:
using ConceptPointer = typename JobType::ConceptPointer; using ConceptPointer = typename JobType::ConceptPointer;
using Jobs = std::vector<JobType>; using Jobs = std::vector<JobType>;
Task(std::string name, ConceptPointer concept) : JobType(name, concept) {} Task(ConceptPointer concept) : JobType(concept) {}
class TaskConcept : public Concept { class TaskConcept : public Concept {
public: public:
@ -259,11 +261,11 @@ public:
return jobIt; return jobIt;
} }
TaskConcept(const Varying& input, QConfigPointer config) : Concept(config), _input(input) {} TaskConcept(const std::string& name, const Varying& input, QConfigPointer config) : Concept(name, config), _input(input) {}
// Create a new job in the container's queue; returns the job's output // Create a new job in the container's queue; returns the job's output
template <class NT, class... NA> const Varying addJob(std::string name, const Varying& input, NA&&... args) { template <class NT, class... NA> const Varying addJob(std::string name, const Varying& input, NA&&... args) {
_jobs.emplace_back(name, (NT::JobModel::create(input, std::forward<NA>(args)...))); _jobs.emplace_back((NT::JobModel::create(name, input, std::forward<NA>(args)...)));
// Conect the child config to this task's config // Conect the child config to this task's config
std::static_pointer_cast<TaskConfig>(Concept::getConfiguration())->connectChildConfig(_jobs.back().getConfiguration(), name); std::static_pointer_cast<TaskConfig>(Concept::getConfiguration())->connectChildConfig(_jobs.back().getConfiguration(), name);
@ -284,16 +286,18 @@ public:
Data _data; Data _data;
TaskModel(const Varying& input, QConfigPointer config) : TaskModel(const std::string& name, const Varying& input, QConfigPointer config) :
TaskConcept(input, config), TaskConcept(name, input, config),
_data(Data()) {} _data(Data()) {}
template <class... A> template <class... A>
static std::shared_ptr<TaskModel> create(const Varying& input, A&&... args) { static std::shared_ptr<TaskModel> create(const std::string& name, const Varying& input, A&&... args) {
auto model = std::make_shared<TaskModel>(input, std::make_shared<C>()); auto model = std::make_shared<TaskModel>(name, input, std::make_shared<C>());
model->_data.build(*(model), model->_input, model->_output, std::forward<A>(args)...);
{
Duration profileRange(trace_render(), ("build::" + model->getName()).c_str());
model->_data.build(*(model), model->_input, model->_output, std::forward<A>(args)...);
}
// Recreate the Config to use the templated type // Recreate the Config to use the templated type
model->createConfiguration(); model->createConfiguration();
model->applyConfiguration(); model->applyConfiguration();
@ -302,9 +306,9 @@ public:
} }
template <class... A> template <class... A>
static std::shared_ptr<TaskModel> create(A&&... args) { static std::shared_ptr<TaskModel> create(const std::string& name, A&&... args) {
const auto input = Varying(Input()); const auto input = Varying(Input());
return create(input, std::forward<A>(args)...); return create(name, input, std::forward<A>(args)...);
} }
void createConfiguration() { void createConfiguration() {
@ -326,6 +330,7 @@ public:
} }
void applyConfiguration() override { void applyConfiguration() override {
Duration profileRange(trace_render(), ("configure::" + getName()).c_str());
jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config)); jobConfigure(_data, *std::static_pointer_cast<C>(Concept::_config));
for (auto& job : TaskConcept::_jobs) { for (auto& job : TaskConcept::_jobs) {
job.applyConfiguration(); job.applyConfiguration();