Adding the timing for GPU support with a simpelr JobConfig

This commit is contained in:
samcake 2016-08-30 12:22:21 -07:00
parent 74fac8c7c9
commit faef8a9930
16 changed files with 146 additions and 89 deletions

View file

@ -25,6 +25,7 @@ void GLBackend::do_beginQuery(const Batch& batch, size_t paramOffset) {
auto query = batch._queries.get(batch._params[paramOffset]._uint); auto query = batch._queries.get(batch._params[paramOffset]._uint);
GLQuery* glquery = syncGPUObject(*query); GLQuery* glquery = syncGPUObject(*query);
if (glquery) { if (glquery) {
glGetInteger64v(GL_TIMESTAMP, (GLint64*)&glquery->_batchElapsedTime);
if (timeElapsed) { if (timeElapsed) {
glBeginQuery(GL_TIME_ELAPSED, glquery->_endqo); glBeginQuery(GL_TIME_ELAPSED, glquery->_endqo);
} else { } else {
@ -43,6 +44,10 @@ void GLBackend::do_endQuery(const Batch& batch, size_t paramOffset) {
} else { } else {
glQueryCounter(glquery->_endqo, GL_TIMESTAMP); glQueryCounter(glquery->_endqo, GL_TIMESTAMP);
} }
GLint64 now;
glGetInteger64v(GL_TIMESTAMP, &now);
glquery->_batchElapsedTime = now - glquery->_batchElapsedTime;
(void)CHECK_GL_ERROR(); (void)CHECK_GL_ERROR();
} }
} }
@ -61,7 +66,7 @@ void GLBackend::do_getQuery(const Batch& batch, size_t paramOffset) {
glGetQueryObjectui64v(glquery->_endqo, GL_QUERY_RESULT, &end); glGetQueryObjectui64v(glquery->_endqo, GL_QUERY_RESULT, &end);
glquery->_result = end - start; glquery->_result = end - start;
} }
query->triggerReturnHandler(glquery->_result); query->triggerReturnHandler(glquery->_result, glquery->_batchElapsedTime);
} }
(void)CHECK_GL_ERROR(); (void)CHECK_GL_ERROR();
} }

View file

@ -48,6 +48,7 @@ public:
const GLuint& _endqo = { _id }; const GLuint& _endqo = { _id };
const GLuint _beginqo = { 0 }; const GLuint _beginqo = { 0 };
GLuint64 _result { (GLuint64)-1 }; GLuint64 _result { (GLuint64)-1 };
GLuint64 _batchElapsedTime { (GLuint64) 0 };
protected: protected:
GLQuery(const std::weak_ptr<GLBackend>& backend, const Query& query, GLuint endId, GLuint beginId) : Parent(backend, query, endId), _beginqo(beginId) {} GLQuery(const std::weak_ptr<GLBackend>& backend, const Query& query, GLuint endId, GLuint beginId) : Parent(backend, query, endId), _beginqo(beginId) {}

View file

@ -24,12 +24,16 @@ Query::~Query()
{ {
} }
double Query::getElapsedTime() const { double Query::getGPUElapsedTime() const {
return ((double)_queryResult) / 1000000.0; return ((double)_queryResult) / 1000000.0;
} }
double Query::getBatchElapsedTime() const {
return ((double)_usecBatchElapsedTime) / 1000000.0;
}
void Query::triggerReturnHandler(uint64_t queryResult) { void Query::triggerReturnHandler(uint64_t queryResult, uint64_t batchElapsedTime) {
_queryResult = queryResult; _queryResult = queryResult;
_usecBatchElapsedTime = batchElapsedTime;
if (_returnHandler) { if (_returnHandler) {
_returnHandler(*this); _returnHandler(*this);
} }
@ -40,8 +44,8 @@ RangeTimer::RangeTimer() {
for (int i = 0; i < QUERY_QUEUE_SIZE; i++) { for (int i = 0; i < QUERY_QUEUE_SIZE; i++) {
_timerQueries.push_back(std::make_shared<gpu::Query>([&, i] (const Query& query) { _timerQueries.push_back(std::make_shared<gpu::Query>([&, i] (const Query& query) {
_tailIndex ++; _tailIndex ++;
auto elapsedTime = query.getElapsedTime(); _movingAverageGPU.addSample(query.getGPUElapsedTime());
_movingAverage.addSample(elapsedTime); _movingAverageBatch.addSample(query.getBatchElapsedTime());
})); }));
} }
} }
@ -66,6 +70,10 @@ void RangeTimer::end(gpu::Batch& batch) {
} }
} }
double RangeTimer::getAverage() const { double RangeTimer::getGPUAverage() const {
return _movingAverage.average; return _movingAverageGPU.average;
}
double RangeTimer::getBatchAverage() const {
return _movingAverageBatch.average;
} }

View file

@ -30,14 +30,17 @@ namespace gpu {
Query(const Handler& returnHandler); Query(const Handler& returnHandler);
~Query(); ~Query();
double getElapsedTime() const; double getGPUElapsedTime() const;
double getBatchElapsedTime() const;
// Only for gpu::Context
const GPUObjectPointer gpuObject {}; const GPUObjectPointer gpuObject {};
void triggerReturnHandler(uint64_t queryResult); void triggerReturnHandler(uint64_t queryResult, uint64_t batchElapsedTime);
protected: protected:
Handler _returnHandler; Handler _returnHandler;
uint64_t _queryResult = 0; uint64_t _queryResult { 0 };
uint64_t _usecBatchElapsedTime { 0 };
}; };
typedef std::shared_ptr<Query> QueryPointer; typedef std::shared_ptr<Query> QueryPointer;
@ -53,7 +56,8 @@ namespace gpu {
void begin(gpu::Batch& batch); void begin(gpu::Batch& batch);
void end(gpu::Batch& batch); void end(gpu::Batch& batch);
double getAverage() const; double getGPUAverage() const;
double getBatchAverage() const;
protected: protected:
@ -62,7 +66,8 @@ namespace gpu {
gpu::Queries _timerQueries; gpu::Queries _timerQueries;
int _headIndex = -1; int _headIndex = -1;
int _tailIndex = -1; int _tailIndex = -1;
MovingAverage<double, QUERY_QUEUE_SIZE * 2> _movingAverage; MovingAverage<double, QUERY_QUEUE_SIZE * 2> _movingAverageGPU;
MovingAverage<double, QUERY_QUEUE_SIZE * 2> _movingAverageBatch;
int rangeIndex(int index) const { return (index % QUERY_QUEUE_SIZE); } int rangeIndex(int index) const { return (index % QUERY_QUEUE_SIZE); }
}; };

View file

@ -432,7 +432,8 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
}); });
// Update the timer // Update the timer
std::static_pointer_cast<Config>(renderContext->jobConfig)->gpuTime = _gpuTimer.getAverage(); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->setGPUBatchRunTime(_gpuTimer.getGPUAverage(), _gpuTimer.getBatchAverage());
} }

View file

@ -53,7 +53,7 @@ protected:
using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>; using AmbientOcclusionFramebufferPointer = std::shared_ptr<AmbientOcclusionFramebuffer>;
class AmbientOcclusionEffectConfig : public render::Job::Config::Persistent { class AmbientOcclusionEffectConfig : public render::GPUJobConfig::Persistent {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty) Q_PROPERTY(bool enabled MEMBER enabled NOTIFY dirty)
Q_PROPERTY(bool ditheringEnabled MEMBER ditheringEnabled NOTIFY dirty) Q_PROPERTY(bool ditheringEnabled MEMBER ditheringEnabled NOTIFY dirty)
@ -68,9 +68,9 @@ class AmbientOcclusionEffectConfig : public render::Job::Config::Persistent {
Q_PROPERTY(int numSamples MEMBER numSamples WRITE setNumSamples) Q_PROPERTY(int numSamples MEMBER numSamples WRITE setNumSamples)
Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel WRITE setResolutionLevel) Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel WRITE setResolutionLevel)
Q_PROPERTY(int blurRadius MEMBER blurRadius WRITE setBlurRadius) Q_PROPERTY(int blurRadius MEMBER blurRadius WRITE setBlurRadius)
Q_PROPERTY(double gpuTime READ getGpuTime)
public: public:
AmbientOcclusionEffectConfig() : render::Job::Config::Persistent("Ambient Occlusion", false) {} AmbientOcclusionEffectConfig() : render::GPUJobConfig::Persistent("Ambient Occlusion", false) {}
const int MAX_RESOLUTION_LEVEL = 4; const int MAX_RESOLUTION_LEVEL = 4;
const int MAX_BLUR_RADIUS = 6; const int MAX_BLUR_RADIUS = 6;
@ -84,7 +84,6 @@ public:
void setNumSamples(int samples) { numSamples = std::max(1.0f, (float)samples); emit dirty(); } void setNumSamples(int samples) { numSamples = std::max(1.0f, (float)samples); emit dirty(); }
void setResolutionLevel(int level) { resolutionLevel = std::max(0, std::min(level, MAX_RESOLUTION_LEVEL)); emit dirty(); } void setResolutionLevel(int level) { resolutionLevel = std::max(0, std::min(level, MAX_RESOLUTION_LEVEL)); emit dirty(); }
void setBlurRadius(int radius) { blurRadius = std::max(0, std::min(MAX_BLUR_RADIUS, radius)); emit dirty(); } void setBlurRadius(int radius) { blurRadius = std::max(0, std::min(MAX_BLUR_RADIUS, radius)); emit dirty(); }
double getGpuTime() { return gpuTime; }
float radius{ 0.5f }; float radius{ 0.5f };
float perspectiveScale{ 1.0f }; float perspectiveScale{ 1.0f };
@ -99,7 +98,6 @@ public:
bool ditheringEnabled{ true }; // randomize the distribution of taps per pixel, should always be true bool ditheringEnabled{ true }; // randomize the distribution of taps per pixel, should always be true
bool borderingEnabled{ true }; // avoid evaluating information from non existing pixels out of the frame, should always be true bool borderingEnabled{ true }; // avoid evaluating information from non existing pixels out of the frame, should always be true
bool fetchMipsEnabled{ true }; // fetch taps in sub mips to otpimize cache, should always be true bool fetchMipsEnabled{ true }; // fetch taps in sub mips to otpimize cache, should always be true
double gpuTime{ 0.0 };
signals: signals:
void dirty(); void dirty();

View file

@ -714,5 +714,5 @@ void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderCo
}); });
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage(); config->setGPUBatchRunTime(_gpuTimer.getGPUAverage(), _gpuTimer.getBatchAverage());
} }

View file

@ -161,21 +161,7 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
}; };
using RenderDeferredConfig = render::GPUJobConfig;
class RenderDeferredConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime)
public:
RenderDeferredConfig() : render::Job::Config(true) {}
double getGpuTime() { return gpuTime; }
double gpuTime{ 0.0 };
signals:
void dirty();
};
class RenderDeferred { class RenderDeferred {
public: public:

View file

@ -245,7 +245,7 @@ void EndGPURangeTimer::run(const render::SceneContextPointer& sceneContext, cons
}); });
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = timer->getAverage(); config->setGPUBatchRunTime(timer->getGPUAverage(), timer->getBatchAverage());
} }

View file

@ -29,18 +29,8 @@ protected:
gpu::RangeTimerPointer _gpuTimer; gpu::RangeTimerPointer _gpuTimer;
}; };
using GPURangeTimerConfig = render::GPUJobConfig;
class GPURangeTimerConfig : public render::Job::Config {
Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime)
public:
double getGpuTime() { return gpuTime; }
protected:
friend class EndGPURangeTimer;
double gpuTime;
};
class EndGPURangeTimer { class EndGPURangeTimer {
public: public:
using Config = GPURangeTimerConfig; using Config = GPURangeTimerConfig;
@ -143,16 +133,7 @@ protected:
gpu::PipelinePointer getOpaquePipeline(); gpu::PipelinePointer getOpaquePipeline();
}; };
class DrawBackgroundDeferredConfig : public render::Job::Config { using DrawBackgroundDeferredConfig = render::GPUJobConfig;
Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime)
public:
double getGpuTime() { return gpuTime; }
protected:
friend class DrawBackgroundDeferred;
double gpuTime;
};
class DrawBackgroundDeferred { class DrawBackgroundDeferred {
public: public:
@ -211,6 +192,8 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer); void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer);
}; };
using RenderDeferredTaskConfig = render::GPUTaskConfig;
/**
class RenderDeferredTaskConfig : public render::Task::Config { class RenderDeferredTaskConfig : public render::Task::Config {
Q_OBJECT Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime) Q_PROPERTY(double gpuTime READ getGpuTime)
@ -220,7 +203,7 @@ public:
protected: protected:
friend class RenderDeferredTask; friend class RenderDeferredTask;
double gpuTime; double gpuTime;
}; };*/
class RenderDeferredTask : public render::Task { class RenderDeferredTask : public render::Task {
public: public:

View file

@ -201,7 +201,7 @@ void LinearDepthPass::run(const render::SceneContextPointer& sceneContext, const
}); });
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage(); config->setGPUBatchRunTime(_gpuTimer.getGPUAverage(), _gpuTimer.getBatchAverage());
} }
@ -524,7 +524,7 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig); auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
config->gpuTime = _gpuTimer.getAverage(); config->setGPUBatchRunTime(_gpuTimer.getGPUAverage(), _gpuTimer.getBatchAverage());
} }

View file

@ -62,20 +62,15 @@ protected:
using LinearDepthFramebufferPointer = std::shared_ptr<LinearDepthFramebuffer>; using LinearDepthFramebufferPointer = std::shared_ptr<LinearDepthFramebuffer>;
using LinearDepthPassConfig = render::GPUJobConfig;
class LinearDepthPassConfig : public render::Job::Config { /*
class LinearDepthPassConfig : public render::GPUJobConfig {
Q_OBJECT Q_OBJECT
Q_PROPERTY(double gpuTime READ getGpuTime)
public: public:
LinearDepthPassConfig() : render::Job::Config(true) {} LinearDepthPassConfig() : render::GPUJobConfig(true) {}
double getGpuTime() { return gpuTime; }
double gpuTime{ 0.0 };
signals: signals:
void dirty(); void dirty();
}; };*/
class LinearDepthPass { class LinearDepthPass {
public: public:
@ -148,7 +143,7 @@ protected:
using SurfaceGeometryFramebufferPointer = std::shared_ptr<SurfaceGeometryFramebuffer>; using SurfaceGeometryFramebufferPointer = std::shared_ptr<SurfaceGeometryFramebuffer>;
class SurfaceGeometryPassConfig : public render::Job::Config { class SurfaceGeometryPassConfig : public render::GPUJobConfig {
Q_OBJECT Q_OBJECT
Q_PROPERTY(float depthThreshold MEMBER depthThreshold NOTIFY dirty) Q_PROPERTY(float depthThreshold MEMBER depthThreshold NOTIFY dirty)
Q_PROPERTY(float basisScale MEMBER basisScale NOTIFY dirty) Q_PROPERTY(float basisScale MEMBER basisScale NOTIFY dirty)
@ -158,9 +153,8 @@ class SurfaceGeometryPassConfig : public render::Job::Config {
Q_PROPERTY(float diffuseFilterScale MEMBER diffuseFilterScale NOTIFY dirty) Q_PROPERTY(float diffuseFilterScale MEMBER diffuseFilterScale NOTIFY dirty)
Q_PROPERTY(float diffuseDepthThreshold MEMBER diffuseDepthThreshold NOTIFY dirty) Q_PROPERTY(float diffuseDepthThreshold MEMBER diffuseDepthThreshold NOTIFY dirty)
Q_PROPERTY(double gpuTime READ getGpuTime)
public: public:
SurfaceGeometryPassConfig() : render::Job::Config(true) {} SurfaceGeometryPassConfig() : render::GPUJobConfig(true) {}
float depthThreshold{ 5.0f }; // centimeters float depthThreshold{ 5.0f }; // centimeters
float basisScale{ 1.0f }; float basisScale{ 1.0f };
@ -169,10 +163,6 @@ public:
float diffuseFilterScale{ 0.2f }; float diffuseFilterScale{ 0.2f };
float diffuseDepthThreshold{ 1.0f }; float diffuseDepthThreshold{ 1.0f };
double getGpuTime() { return gpuTime; }
double gpuTime{ 0.0 };
signals: signals:
void dirty(); void dirty();
}; };

View file

@ -334,9 +334,9 @@ protected:
// A default Config is always on; to create an enableable Config, use the ctor JobConfig(bool enabled) // A default Config is always on; to create an enableable Config, use the ctor JobConfig(bool enabled)
class JobConfig : public QObject { class JobConfig : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(quint64 cpuRunTime READ getCPUTRunTime NOTIFY newStats()) Q_PROPERTY(double cpuRunTime READ getCPURunTime NOTIFY newStats()) //ms
quint64 _CPURunTime{ 0 }; double _msCPURunTime{ 0.0 };
public: public:
using Persistent = PersistentConfig<JobConfig>; using Persistent = PersistentConfig<JobConfig>;
@ -364,8 +364,8 @@ public:
// Running Time measurement // Running Time measurement
// The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated // The new stats signal is emitted once per run time of a job when stats (cpu runtime) are updated
void setCPURunTime(quint64 ustime) { _CPURunTime = ustime; emit newStats(); } void setCPURunTime(double mstime) { _msCPURunTime = mstime; emit newStats(); }
quint64 getCPUTRunTime() const { return _CPURunTime; } double getCPURunTime() const { return _msCPURunTime; }
public slots: public slots:
void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); } void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); }
@ -418,6 +418,46 @@ template <class T, class I, class O> void jobRun(T& data, const SceneContextPoin
data.run(sceneContext, renderContext, input, output); data.run(sceneContext, renderContext, input, output);
} }
class GPUJobConfig : public JobConfig {
Q_OBJECT
Q_PROPERTY(double gpuRunTime READ getGPURunTime)
Q_PROPERTY(double batchRunTime READ getBatchRunTime)
double _msGPURunTime { 0.0 };
double _msBatchRunTime { 0.0 };
public:
using Persistent = PersistentConfig<GPUJobConfig>;
GPUJobConfig() = default;
GPUJobConfig(bool enabled) : JobConfig(enabled) {}
// Running Time measurement on GPU and for Batch execution
void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; }
double getGPURunTime() const { return _msGPURunTime; }
double getBatchRunTime() const { return _msBatchRunTime; }
};
class GPUTaskConfig : public TaskConfig {
Q_OBJECT
Q_PROPERTY(double gpuRunTime READ getGPURunTime)
Q_PROPERTY(double batchRunTime READ getBatchRunTime)
double _msGPURunTime { 0.0 };
double _msBatchRunTime { 0.0 };
public:
using Persistent = PersistentConfig<GPUTaskConfig>;
GPUTaskConfig() = default;
GPUTaskConfig(bool enabled) : TaskConfig(enabled) {}
// Running Time measurement on GPU and for Batch execution
void setGPUBatchRunTime(double msGpuTime, double msBatchTime) { _msGPURunTime = msGpuTime; _msBatchRunTime = msBatchTime; }
double getGPURunTime() const { return _msGPURunTime; }
double getBatchRunTime() const { return _msBatchRunTime; }
};
class Job { class Job {
public: public:
using Config = JobConfig; using Config = JobConfig;
@ -439,7 +479,7 @@ public:
virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0; virtual void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) = 0;
protected: protected:
void setCPURunTime(quint64 ustime) { std::static_pointer_cast<Config>(_config)->setCPURunTime(ustime); } void setCPURunTime(double mstime) { std::static_pointer_cast<Config>(_config)->setCPURunTime(mstime); }
QConfigPointer _config; QConfigPointer _config;
@ -502,7 +542,7 @@ public:
_concept->run(sceneContext, renderContext); _concept->run(sceneContext, renderContext);
_concept->setCPURunTime(usecTimestampNow() - start); _concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000000.0);
} }
protected: protected:

View file

@ -78,7 +78,7 @@ Column {
valueNumDigits: "4" valueNumDigits: "4"
plots: [ plots: [
{ {
prop: "gpuTime", prop: "gpuRunTime",
label: "gpu", label: "gpu",
color: "#FFFFFF" color: "#FFFFFF"
} }

View file

@ -213,7 +213,7 @@ Item {
height: parent.evalEvenHeight() height: parent.evalEvenHeight()
object: parent.drawOpaqueConfig object: parent.drawOpaqueConfig
valueUnit: "ms" valueUnit: "ms"
valueScale: 1000 valueScale: 1
valueNumDigits: "1" valueNumDigits: "1"
plots: [ plots: [
{ {

View file

@ -39,31 +39,71 @@ Item {
plots: [ plots: [
{ {
object: Render.getConfig("OpaqueRangeTimer"), object: Render.getConfig("OpaqueRangeTimer"),
prop: "gpuTime", prop: "gpuRunTime",
label: "Opaque", label: "Opaque",
color: "#FFFFFF" color: "#FFFFFF"
}, },
{ {
object: Render.getConfig("LinearDepth"), object: Render.getConfig("LinearDepth"),
prop: "gpuTime", prop: "gpuRunTime",
label: "LinearDepth", label: "LinearDepth",
color: "#00FF00" color: "#00FF00"
},{ },{
object: Render.getConfig("SurfaceGeometry"), object: Render.getConfig("SurfaceGeometry"),
prop: "gpuTime", prop: "gpuRunTime",
label: "SurfaceGeometry", label: "SurfaceGeometry",
color: "#00FFFF" color: "#00FFFF"
}, },
{ {
object: Render.getConfig("RenderDeferred"), object: Render.getConfig("RenderDeferred"),
prop: "gpuTime", prop: "gpuRunTime",
label: "DeferredLighting", label: "DeferredLighting",
color: "#FF00FF" color: "#FF00FF"
} }
, ,
{ {
object: Render.getConfig("ToneAndPostRangeTimer"), object: Render.getConfig("ToneAndPostRangeTimer"),
prop: "gpuTime", prop: "gpuRunTime",
label: "tone and post",
color: "#FF0000"
}
]
}
PlotPerf {
title: "Timing"
height: parent.evalEvenHeight()
object: parent.drawOpaqueConfig
valueUnit: "ms"
valueScale: 1
valueNumDigits: "4"
plots: [
{
object: Render.getConfig("OpaqueRangeTimer"),
prop: "batchRunTime",
label: "Opaque",
color: "#FFFFFF"
},
{
object: Render.getConfig("LinearDepth"),
prop: "batchRunTime",
label: "LinearDepth",
color: "#00FF00"
},{
object: Render.getConfig("SurfaceGeometry"),
prop: "batchRunTime",
label: "SurfaceGeometry",
color: "#00FFFF"
},
{
object: Render.getConfig("RenderDeferred"),
prop: "batchRunTime",
label: "DeferredLighting",
color: "#FF00FF"
}
,
{
object: Render.getConfig("ToneAndPostRangeTimer"),
prop: "batchRunTime",
label: "tone and post", label: "tone and post",
color: "#FF0000" color: "#FF0000"
} }