Support for canceling preprocess tasks -- fixes Bug #9

metadata
Wenzel Jakob 2010-09-14 01:45:24 +02:00
parent 59ff88d45a
commit 74f6e540e2
14 changed files with 110 additions and 31 deletions

View File

@ -41,7 +41,7 @@ public:
* which have been made available to all local and remote workers. * which have been made available to all local and remote workers.
* The default implementation simply returns. * The default implementation simply returns.
*/ */
virtual void preprocess(const Scene *scene, RenderQueue *queue, virtual bool preprocess(const Scene *scene, RenderQueue *queue,
const RenderJob *job, int sceneResID, int cameraResID, const RenderJob *job, int sceneResID, int cameraResID,
int samplerResID); int samplerResID);

View File

@ -86,7 +86,7 @@ public:
* which have been made available to all local and remote workers. * which have been made available to all local and remote workers.
* Returns true upon successful completion. * Returns true upon successful completion.
*/ */
void preprocess(RenderQueue *queue, const RenderJob *job, bool preprocess(RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID); int sceneResID, int cameraResID, int samplerResID);
/** /**

View File

@ -34,9 +34,12 @@ public:
* resource IDs of the associated scene, camera and sample generator, * resource IDs of the associated scene, camera and sample generator,
* which have been made available to all local and remote workers. * which have been made available to all local and remote workers.
*/ */
virtual void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, virtual bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) = 0; int sceneResID, int cameraResID, int samplerResID) = 0;
/// Cancel any running pre-process tasks
virtual void cancel() = 0;
/// Return the list of shapes associated with this subsurface integrator /// Return the list of shapes associated with this subsurface integrator
inline const std::vector<Shape *> getShapes() const { return m_shapes; } inline const std::vector<Shape *> getShapes() const { return m_shapes; }

View File

@ -87,9 +87,10 @@ public:
m_subIntegrator->configureSampler(sampler); m_subIntegrator->configureSampler(sampler);
} }
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); if (!SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID))
return false;
if (m_subIntegrator == NULL) if (m_subIntegrator == NULL)
Log(EError, "No sub-integrator was specified!"); Log(EError, "No sub-integrator was specified!");
Sampler *sampler = static_cast<Sampler *>(Scheduler::getInstance()->getResource(samplerResID, 0)); Sampler *sampler = static_cast<Sampler *>(Scheduler::getInstance()->getResource(samplerResID, 0));
@ -97,7 +98,8 @@ public:
if (sampler->getClass()->getName() != "IndependentSampler") if (sampler->getClass()->getName() != "IndependentSampler")
Log(EError, "The error-controlling integrator should only be " Log(EError, "The error-controlling integrator should only be "
"used in conjunction with the independent sampler"); "used in conjunction with the independent sampler");
m_subIntegrator->preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); if (!m_subIntegrator->preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID))
return false;
Vector2i filmSize = camera->getFilm()->getSize(); Vector2i filmSize = camera->getFilm()->getSize();
bool needsLensSample = camera->needsLensSample(); bool needsLensSample = camera->needsLensSample();
@ -122,6 +124,7 @@ public:
m_quantile = (Float) normalQuantile(1-m_pval/2); m_quantile = (Float) normalQuantile(1-m_pval/2);
Log(EInfo, "Configuring for a %.1f%% confidence interval, quantile=%f, avg. luminance=%f", Log(EInfo, "Configuring for a %.1f%% confidence interval, quantile=%f, avg. luminance=%f",
(1-m_pval)*100, m_quantile, m_averageLuminance); (1-m_pval)*100, m_quantile, m_averageLuminance);
return true;
} }
void renderBlock(const Scene *scene, const Camera *camera, Sampler *sampler, void renderBlock(const Scene *scene, const Camera *camera, Sampler *sampler,
@ -239,6 +242,12 @@ public:
m_subIntegrator->wakeup(params); m_subIntegrator->wakeup(params);
} }
void cancel() {
SampleIntegrator::cancel();
m_subIntegrator->cancel();
}
const Integrator *getSubIntegrator() const { const Integrator *getSubIntegrator() const {
return m_subIntegrator.get(); return m_subIntegrator.get();
} }

View File

@ -147,14 +147,16 @@ public:
} }
} }
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); if (!SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID))
return false;
if (m_subIntegrator == NULL) if (m_subIntegrator == NULL)
Log(EError, "No sub-integrator was specified!"); Log(EError, "No sub-integrator was specified!");
m_subIntegrator->preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); if (!m_subIntegrator->preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID))
return false;
ref<Scheduler> sched = Scheduler::getInstance(); ref<Scheduler> sched = Scheduler::getInstance();
m_irrCache = new IrradianceCache(scene->getAABB()); m_irrCache = new IrradianceCache(scene->getAABB());
@ -185,6 +187,7 @@ public:
int subIntegratorResID = sched->registerResource(m_subIntegrator); int subIntegratorResID = sched->registerResource(m_subIntegrator);
ref<OvertureProcess> proc = new OvertureProcess(job, m_resolution, m_gradients, ref<OvertureProcess> proc = new OvertureProcess(job, m_resolution, m_gradients,
m_clampNeighbor, m_clampScreen, m_influenceMin, m_influenceMax, m_quality); m_clampNeighbor, m_clampScreen, m_influenceMin, m_influenceMax, m_quality);
m_proc = proc;
proc->bindResource("scene", sceneResID); proc->bindResource("scene", sceneResID);
proc->bindResource("camera", cameraResID); proc->bindResource("camera", cameraResID);
proc->bindResource("subIntegrator", subIntegratorResID); proc->bindResource("subIntegrator", subIntegratorResID);
@ -192,9 +195,12 @@ public:
sched->schedule(proc); sched->schedule(proc);
sched->unregisterResource(subIntegratorResID); sched->unregisterResource(subIntegratorResID);
sched->wait(proc); sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess) if (proc->getReturnStatus() != ParallelProcess::ESuccess) {
Log(EError, "The overture pass did not complete sucessfully!"); Log(EWarn, "The overture pass did not complete sucessfully!");
return false;
}
ref<const IrradianceRecordVector> vec = proc->getSamples(); ref<const IrradianceRecordVector> vec = proc->getSamples();
Log(EDebug, "Overture pass generated %i irradiance samples", vec->size()); Log(EDebug, "Overture pass generated %i irradiance samples", vec->size());
@ -203,6 +209,16 @@ public:
m_irrCache->setQuality(m_quality * m_qualityAdjustment); m_irrCache->setQuality(m_quality * m_qualityAdjustment);
} }
return true;
}
void cancel() {
if (m_proc) {
Scheduler::getInstance()->cancel(m_proc);
} else {
SampleIntegrator::cancel();
m_subIntegrator->cancel();
}
} }
Spectrum Li(const RayDifferential &ray, RadianceQueryRecord &rRec) const { Spectrum Li(const RayDifferential &ray, RadianceQueryRecord &rRec) const {
@ -316,6 +332,7 @@ private:
mutable ThreadLocal<Sampler> m_sampleGenerator; mutable ThreadLocal<Sampler> m_sampleGenerator;
mutable ref<IrradianceCache> m_irrCache; mutable ref<IrradianceCache> m_irrCache;
ref<SampleIntegrator> m_subIntegrator; ref<SampleIntegrator> m_subIntegrator;
ref<ParallelProcess> m_proc;
int m_resolution; int m_resolution;
Float m_influenceMin, m_influenceMax; Float m_influenceMin, m_influenceMax;
Float m_quality, m_qualityAdjustment; Float m_quality, m_qualityAdjustment;

View File

@ -80,7 +80,7 @@ public:
stream->writeBool(m_multipleScattering); stream->writeBool(m_multipleScattering);
} }
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
@ -91,6 +91,7 @@ public:
if (scene->getSubsurfaceIntegrators().size() > 0) if (scene->getSubsurfaceIntegrators().size() > 0)
Log(EError, "Subsurface integrators are not supported by the particle tracer!"); Log(EError, "Subsurface integrators are not supported by the particle tracer!");
m_sampleCount = scene->getSampler()->getSampleCount() * size.x * size.y; m_sampleCount = scene->getSampler()->getSampleCount() * size.x * size.y;
return true;
} }
void cancel() { void cancel() {

View File

@ -114,7 +114,7 @@ public:
sampler->request2DArray(m_glossySamples); sampler->request2DArray(m_glossySamples);
} }
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
/* Create a deterministic sampler for the photon gathering step */ /* Create a deterministic sampler for the photon gathering step */
@ -151,8 +151,13 @@ public:
proc->bindResource("scene", sceneResID); proc->bindResource("scene", sceneResID);
proc->bindResource("sampler", qmcSamplerID); proc->bindResource("sampler", qmcSamplerID);
m_proc = proc;
sched->schedule(proc); sched->schedule(proc);
sched->wait(proc); sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
return false;
m_globalPhotonMap = proc->getPhotonMap(); m_globalPhotonMap = proc->getPhotonMap();
m_globalPhotonMap->setScale(1 / (Float) proc->getShotPhotons()); m_globalPhotonMap->setScale(1 / (Float) proc->getShotPhotons());
@ -175,8 +180,13 @@ public:
proc->bindResource("scene", sceneResID); proc->bindResource("scene", sceneResID);
proc->bindResource("sampler", qmcSamplerID); proc->bindResource("sampler", qmcSamplerID);
m_proc = proc;
sched->schedule(proc); sched->schedule(proc);
sched->wait(proc); sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
return false;
m_causticPhotonMap = proc->getPhotonMap(); m_causticPhotonMap = proc->getPhotonMap();
m_causticPhotonMap->setScale(1 / (Float) proc->getShotPhotons()); m_causticPhotonMap->setScale(1 / (Float) proc->getShotPhotons());
@ -199,8 +209,13 @@ public:
proc->bindResource("scene", sceneResID); proc->bindResource("scene", sceneResID);
proc->bindResource("sampler", qmcSamplerID); proc->bindResource("sampler", qmcSamplerID);
m_proc = proc;
sched->schedule(proc); sched->schedule(proc);
sched->wait(proc); sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
return false;
m_volumePhotonMap = proc->getPhotonMap(); m_volumePhotonMap = proc->getPhotonMap();
m_volumePhotonMap->setScale(1 / (Float) proc->getShotPhotons()); m_volumePhotonMap->setScale(1 / (Float) proc->getShotPhotons());
@ -212,6 +227,7 @@ public:
} }
sched->unregisterResource(qmcSamplerID); sched->unregisterResource(qmcSamplerID);
return true;
} }
/// Specify globally shared resources /// Specify globally shared resources
@ -240,6 +256,12 @@ public:
} }
void cancel() {
SampleIntegrator::cancel();
if (m_proc)
Scheduler::getInstance()->cancel(m_proc);
}
Spectrum Li(const RayDifferential &ray, RadianceQueryRecord &rRec) const { Spectrum Li(const RayDifferential &ray, RadianceQueryRecord &rRec) const {
Spectrum Li(0.0f), LiVol(0.0f); Spectrum Li(0.0f), LiVol(0.0f);
Intersection &its = rRec.its; Intersection &its = rRec.its;
@ -375,6 +397,7 @@ private:
ref<PhotonMap> m_globalPhotonMap; ref<PhotonMap> m_globalPhotonMap;
ref<PhotonMap> m_causticPhotonMap; ref<PhotonMap> m_causticPhotonMap;
ref<PhotonMap> m_volumePhotonMap; ref<PhotonMap> m_volumePhotonMap;
ref<ParallelProcess> m_proc;
SampleIntegrator *m_parentIntegrator; SampleIntegrator *m_parentIntegrator;
int m_globalPhotonMapID, m_causticPhotonMapID, m_volumePhotonMapID; int m_globalPhotonMapID, m_causticPhotonMapID, m_volumePhotonMapID;
size_t m_globalPhotons, m_causticPhotons, m_volumePhotons; size_t m_globalPhotons, m_causticPhotons, m_volumePhotons;

View File

@ -90,7 +90,7 @@ public:
m_running = false; m_running = false;
} }
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
@ -102,6 +102,7 @@ public:
m_initialRadius = std::min(rad / filmSize.x, rad / filmSize.y) * 5; m_initialRadius = std::min(rad / filmSize.x, rad / filmSize.y) * 5;
} }
return true;
} }
bool render(Scene *scene, RenderQueue *queue, bool render(Scene *scene, RenderQueue *queue,

View File

@ -86,7 +86,7 @@ public:
} }
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
@ -98,6 +98,7 @@ public:
m_initialRadius = std::min(rad / filmSize.x, rad / filmSize.y) * 5; m_initialRadius = std::min(rad / filmSize.x, rad / filmSize.y) * 5;
} }
return true;
} }
bool render(Scene *scene, RenderQueue *queue, bool render(Scene *scene, RenderQueue *queue,

View File

@ -70,7 +70,7 @@ public:
m_shaderManager->drawBackground(clipToWorld, camPos); m_shaderManager->drawBackground(clipToWorld, camPos);
} }
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID); Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
@ -80,6 +80,7 @@ public:
m_vpls[i].P *= normalization; m_vpls[i].P *= normalization;
Log(EInfo, "Generated %i virtual point lights", m_vpls.size()); Log(EInfo, "Generated %i virtual point lights", m_vpls.size());
} }
return true;
} }
void cancel() { void cancel() {

View File

@ -32,8 +32,8 @@ Integrator::Integrator(Stream *stream, InstanceManager *manager)
: NetworkedObject(stream, manager) { : NetworkedObject(stream, manager) {
} }
void Integrator::preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool Integrator::preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { } int sceneResID, int cameraResID, int samplerResID) { return true; }
void Integrator::postprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, void Integrator::postprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { } int sceneResID, int cameraResID, int samplerResID) { }
void Integrator::configureSampler(Sampler *sampler) { } void Integrator::configureSampler(Sampler *sampler) { }
@ -98,6 +98,7 @@ Spectrum SampleIntegrator::E(const Scene *scene, const Point &p, const Normal &n
} }
void SampleIntegrator::cancel() { void SampleIntegrator::cancel() {
if (m_process)
Scheduler::getInstance()->cancel(m_process); Scheduler::getInstance()->cancel(m_process);
} }

View File

@ -107,14 +107,20 @@ void RenderJob::run() {
bool cancelled = false; bool cancelled = false;
m_scene->initialize(); m_scene->initialize();
try { try {
m_scene->preprocess(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID); if (!m_scene->preprocess(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID)) {
cancelled = true;
Log(EWarn, "Preprocessing of scene \"%s\" did not complete successfully!",
m_scene->getSourceFile().leaf().c_str());
}
if (!cancelled) {
if (!m_scene->render(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID)) { if (!m_scene->render(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID)) {
cancelled = true; cancelled = true;
Log(EWarn, "Rendering of scene \"%s\" did not complete successfully!", Log(EWarn, "Rendering of scene \"%s\" did not complete successfully!",
m_scene->getSourceFile().leaf().c_str()); m_scene->getSourceFile().leaf().c_str());
} }
m_scene->postprocess(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID); m_scene->postprocess(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID);
}
if (m_testSupervisor.get()) if (m_testSupervisor.get())
m_testSupervisor->analyze(m_scene); m_testSupervisor->analyze(m_scene);

View File

@ -282,23 +282,26 @@ void Scene::initialize() {
} }
} }
void Scene::preprocess(RenderQueue *queue, const RenderJob *job, bool Scene::preprocess(RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
/* Pre-process step for the main scene integrator */ /* Pre-process step for the main scene integrator */
m_integrator->preprocess(this, queue, job, if (!m_integrator->preprocess(this, queue, job,
sceneResID, cameraResID, samplerResID); sceneResID, cameraResID, samplerResID))
return false;
/* Pre-process step for all sub-surface integrators */ /* Pre-process step for all sub-surface integrators */
for (std::vector<Subsurface *>::iterator it = m_ssIntegrators.begin(); for (std::vector<Subsurface *>::iterator it = m_ssIntegrators.begin();
it != m_ssIntegrators.end(); ++it) it != m_ssIntegrators.end(); ++it)
(*it)->preprocess(this, queue, job, if (!(*it)->preprocess(this, queue, job,
sceneResID, cameraResID, samplerResID); sceneResID, cameraResID, samplerResID))
return false;
/* Pre-process step for all participating media */ /* Pre-process step for all participating media */
for (std::vector<Medium *>::iterator it = m_media.begin(); for (std::vector<Medium *>::iterator it = m_media.begin();
it != m_media.end(); ++it) it != m_media.end(); ++it)
(*it)->preprocess(this, queue, job, (*it)->preprocess(this, queue, job,
sceneResID, cameraResID, samplerResID); sceneResID, cameraResID, samplerResID);
return true;
} }
bool Scene::render(RenderQueue *queue, const RenderJob *job, bool Scene::render(RenderQueue *queue, const RenderJob *job,
@ -309,6 +312,9 @@ bool Scene::render(RenderQueue *queue, const RenderJob *job,
} }
void Scene::cancel() { void Scene::cancel() {
for (std::vector<Subsurface *>::iterator it = m_ssIntegrators.begin();
it != m_ssIntegrators.end(); ++it)
(*it)->cancel();
m_integrator->cancel(); m_integrator->cancel();
} }

View File

@ -239,10 +239,10 @@ public:
return 0.5f * temp1 * temp1 * (1.0f + temp2 * temp2); return 0.5f * temp1 * temp1 * (1.0f + temp2 * temp2);
} }
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job, bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { int sceneResID, int cameraResID, int samplerResID) {
if (m_ready) if (m_ready)
return; return true;
if (!scene->getIntegrator()->getClass() if (!scene->getIntegrator()->getClass()
->derivesFrom(SampleIntegrator::m_theClass)) { ->derivesFrom(SampleIntegrator::m_theClass)) {
@ -280,8 +280,12 @@ public:
proc->bindResource("scene", sceneResID); proc->bindResource("scene", sceneResID);
scene->bindUsedResources(proc); scene->bindUsedResources(proc);
m_proc = proc;
sched->schedule(proc); sched->schedule(proc);
sched->wait(proc); sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
return false;
const IrradianceRecordVector &results = *proc->getSamples(); const IrradianceRecordVector &results = *proc->getSamples();
for (size_t i=0; i<results.size(); ++i) for (size_t i=0; i<results.size(); ++i)
@ -291,6 +295,7 @@ public:
m_octreeResID = Scheduler::getInstance()->registerResource(m_octree); m_octreeResID = Scheduler::getInstance()->registerResource(m_octree);
m_ready = true; m_ready = true;
return false;
} }
void wakeup(std::map<std::string, SerializableObject *> &params) { void wakeup(std::map<std::string, SerializableObject *> &params) {
@ -301,6 +306,10 @@ public:
} }
} }
void cancel() {
Scheduler::getInstance()->cancel(m_proc);
}
MTS_DECLARE_CLASS() MTS_DECLARE_CLASS()
private: private:
Float m_minMFP, m_sampleMultiplier; Float m_minMFP, m_sampleMultiplier;
@ -308,6 +317,7 @@ private:
Spectrum m_mfp, m_sigmaTr, m_zr, m_zv, m_alphaPrime; Spectrum m_mfp, m_sigmaTr, m_zr, m_zv, m_alphaPrime;
Spectrum m_sigmaSPrime, m_sigmaTPrime, m_D, m_ssFactor; Spectrum m_sigmaSPrime, m_sigmaTPrime, m_D, m_ssFactor;
ref<IrradianceOctree> m_octree; ref<IrradianceOctree> m_octree;
ref<ParallelProcess> m_proc;
int m_octreeResID, m_octreeIndex; int m_octreeResID, m_octreeIndex;
int m_maxDepth; int m_maxDepth;
bool m_ready, m_requireSample; bool m_ready, m_requireSample;