mitsuba/include/mitsuba/render/renderqueue.h

133 lines
4.0 KiB
C++

/*
This file is part of Mitsuba, a physically based rendering system.
Copyright (c) 2007-2012 by Wenzel Jakob and others.
Mitsuba is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Mitsuba is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if !defined(__MITSUBA_RENDER_RENDERQUEUE_H_)
#define __MITSUBA_RENDER_RENDERQUEUE_H_
#include <mitsuba/mitsuba.h>
#include <mitsuba/render/rectwu.h>
MTS_NAMESPACE_BEGIN
/**
* \brief Abstract render listener - can be used to react to
* progress messages (e.g. in a GUI)
* \ingroup librender
*/
class MTS_EXPORT_RENDER RenderListener : public Object {
public:
/// Called when work has begun in a rectangular image region
virtual void workBeginEvent(const RenderJob *job, const RectangularWorkUnit *wu, int worker);
/// Called when work has finished in a rectangular image region
virtual void workEndEvent(const RenderJob *job, const ImageBlock *wr, bool cancelled);
/// Called when work has been canceled in a rectangular image region
virtual void workCanceledEvent(const RenderJob *job, const Point2i &offset,
const Vector2i &size);
/// Called when the whole target image has been altered in some way.
virtual void refreshEvent(const RenderJob *job);
/// Called when a render job has completed successfully or unsuccessfully
virtual void finishJobEvent(const RenderJob *job, bool cancelled);
MTS_DECLARE_CLASS()
protected:
virtual ~RenderListener() { }
};
/**
* \brief Render queue - used to keep track of a number of scenes
* that are simultaneously being rendered.
*
* This class is also responsible for distributing events about
* in-progress renderings to registered listeners.
*
* \ingroup librender
*/
class MTS_EXPORT_RENDER RenderQueue : public Object {
public:
/// Create a new render queue
RenderQueue();
/// Return the current number of jobs in the queue
inline size_t getJobCount() const { return m_jobs.size(); }
/// Add a render job to the queue
void addJob(RenderJob *thr);
/// Remove a (finished) render job from the queue
void removeJob(RenderJob *thr, bool wasCancelled);
/// Return the amount of time spent rendering the given job (in seconds)
Float getRenderTime(const RenderJob *job) const;
/// Register a render listener
void registerListener(RenderListener *listener);
/// Unregister a render listener
void unregisterListener(RenderListener *listener);
/**
* Wait until the queue contains a certain number
* of scenes (or less).
*/
void waitLeft(size_t njobs) const;
/// Releases resources held by recently finished jobs
void join() const;
/// Cause all render jobs to write out the current image
void flush();
/* Event distribution */
void signalWorkBegin(const RenderJob *job, const RectangularWorkUnit *wu, int worker);
void signalWorkEnd(const RenderJob *job, const ImageBlock *block, bool cancelled);
void signalWorkCanceled(const RenderJob *job, const Point2i &offset, const Vector2i &size);
void signalFinishJob(const RenderJob *job, bool cancelled);
void signalRefresh(const RenderJob *job);
MTS_DECLARE_CLASS()
private:
/// Virtual destructor
virtual ~RenderQueue();
private:
struct JobRecord {
/* Only starting time for now */
unsigned int startTime;
inline JobRecord() { }
inline JobRecord(unsigned int startTime)
: startTime(startTime) {
}
};
std::map<RenderJob *, JobRecord> m_jobs;
mutable std::vector<RenderJob *> m_joinList;
mutable ref<Mutex> m_mutex, m_joinMutex;
mutable ref<ConditionVariable> m_cond;
ref<Timer> m_timer;
std::vector<RenderListener *> m_listeners;
};
MTS_NAMESPACE_END
#endif /* __MITSUBA_RENDER_RENDERQUEUE_H_ */