mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-21 05:00:06 -05:00
960f0e11be
This reverts commit a7b4cc70d6
.
238 lines
8.4 KiB
C++
238 lines
8.4 KiB
C++
#pragma once
|
|
|
|
#include "Utils.h"
|
|
#include "Ember.h"
|
|
#include "DensityFilter.h"
|
|
|
|
/// <summary>
|
|
/// RendererBase, RenderCallback and EmberStats classes.
|
|
/// </summary>
|
|
|
|
namespace EmberNs
|
|
{
|
|
/// <summary>
|
|
/// Function pointers present a major restriction when dealing
|
|
/// with member functions, and that is they can only point to
|
|
/// static ones. So instead of a straight function pointer, use
|
|
/// a callback class with a single virtual callback
|
|
/// member function.
|
|
/// Template argument expected to be float or double.
|
|
/// </summary>
|
|
class EMBER_API RenderCallback
|
|
{
|
|
public:
|
|
RenderCallback() = default;
|
|
RenderCallback(RenderCallback& callback) = delete;
|
|
|
|
/// <summary>
|
|
/// Virtual destructor to ensure anything declared in derived classes gets cleaned up.
|
|
/// </summary>
|
|
virtual ~RenderCallback() = default;
|
|
|
|
/// <summary>
|
|
/// Empty progress function to be implemented in derived classes to take action on progress updates.
|
|
/// </summary>
|
|
/// <param name="ember">The ember currently being rendered</param>
|
|
/// <param name="foo">An extra dummy parameter</param>
|
|
/// <param name="fraction">The progress fraction from 0-100</param>
|
|
/// <param name="stage">The stage of iteration. 1 is iterating, 2 is density filtering, 2 is final accumulation.</param>
|
|
/// <param name="etaMs">The estimated milliseconds to completion of the current stage</param>
|
|
/// <returns>Override should return 0 if an abort is requested, else 1 to continue rendering</returns>
|
|
virtual int ProgressFunc(Ember<float>& ember, void* foo, double fraction, int stage, double etaMs) { return 0; }
|
|
virtual int ProgressFunc(Ember<double>& ember, void* foo, double fraction, int stage, double etaMs) { return 0; }
|
|
};
|
|
|
|
/// <summary>
|
|
/// Render statistics for the number of iterations ran,
|
|
/// number of bad values calculated during iteration, and
|
|
/// the total time for the entire render from the start of
|
|
/// iteration to the end of final accumulation.
|
|
/// </summary>
|
|
class EMBER_API EmberStats
|
|
{
|
|
public:
|
|
/// <summary>
|
|
/// Constructor which sets all values to 0.
|
|
/// </summary>
|
|
EmberStats() noexcept
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void Clear() noexcept
|
|
{
|
|
m_Success = true;
|
|
m_Iters = 0;
|
|
m_Badvals = 0;
|
|
m_IterMs = 0;
|
|
m_RenderMs = 0;
|
|
}
|
|
|
|
EmberStats& operator += (const EmberStats& stats) noexcept
|
|
{
|
|
m_Success &= stats.m_Success;
|
|
m_Iters += stats.m_Iters;
|
|
m_Badvals += stats.m_Badvals;
|
|
m_IterMs += stats.m_IterMs;
|
|
m_RenderMs += stats.m_RenderMs;
|
|
return *this;
|
|
}
|
|
|
|
bool m_Success = true;
|
|
size_t m_Iters, m_Badvals;
|
|
double m_IterMs, m_RenderMs;
|
|
};
|
|
|
|
/// <summary>
|
|
/// The types of available renderers.
|
|
/// Add more in the future as different rendering methods are experimented with.
|
|
/// Possible values might be: CPU+OpenGL, Particle, Inverse.
|
|
/// </summary>
|
|
enum class eRendererType : et { CPU_RENDERER, OPENCL_RENDERER };
|
|
|
|
/// <summary>
|
|
/// A base class with virtual functions to allow both templating and polymorphism to work together.
|
|
/// Derived classes will implement all of these functions.
|
|
/// Note that functions which return a decimal number use the most precise type, double.
|
|
/// </summary>
|
|
class EMBER_API RendererBase : public EmberReport
|
|
{
|
|
public:
|
|
RendererBase();
|
|
RendererBase(const RendererBase& renderer) = delete;
|
|
RendererBase& operator = (const RendererBase& renderer) = delete;
|
|
virtual ~RendererBase() = default;
|
|
|
|
//Non-virtual processing functions.
|
|
void ChangeVal(std::function<void(void)> func, eProcessAction action);
|
|
size_t HistMemoryRequired(size_t strips);
|
|
pair<size_t, size_t> MemoryRequired(size_t strips, bool includeFinal, bool threadedWrite);
|
|
vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>> RandVec();
|
|
bool PrepFinalAccumVector(vector<v4F>& pixels);
|
|
|
|
//Virtual processing functions.
|
|
virtual bool Ok() const;
|
|
virtual size_t MemoryAvailable();
|
|
virtual void SetEmber(const Ember<float>& ember, eProcessAction action = eProcessAction::FULL_RENDER, bool prep = false) { }
|
|
virtual void SetEmber(const Ember<double>& ember, eProcessAction action = eProcessAction::FULL_RENDER, bool prep = false) { }
|
|
virtual bool RandVec(vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>>& randVec);
|
|
|
|
//Abstract processing functions.
|
|
virtual bool CreateDEFilter(bool& newAlloc) = 0;
|
|
virtual bool CreateSpatialFilter(bool& newAlloc) = 0;
|
|
virtual bool CreateTemporalFilter(bool& newAlloc) = 0;
|
|
virtual void Prepare() = 0;
|
|
virtual void ComputeBounds() = 0;
|
|
virtual void ComputeQuality() = 0;
|
|
virtual void ComputeCamera() = 0;
|
|
virtual eRenderStatus Run(vector<v4F>& finalImage, double time = 0, size_t subBatchCountOverride = 0, bool forceOutput = false, size_t finalOffset = 0) = 0;
|
|
virtual EmberImageComments ImageComments(const EmberStats& stats, size_t printEditDepth = 0, bool hexPalette = true) = 0;
|
|
virtual DensityFilterBase* GetDensityFilter() = 0;
|
|
|
|
//Non-virtual renderer properties, getters only.
|
|
size_t SuperRasW() const;
|
|
size_t SuperRasH() const;
|
|
size_t SuperSize() const;
|
|
size_t FinalRowSize() const;
|
|
size_t FinalDimensions() const;
|
|
size_t FinalBufferSize() const;
|
|
size_t PixelSize() const;
|
|
size_t GutterWidth() const;
|
|
size_t DensityFilterOffset() const;
|
|
size_t TotalIterCount(size_t strips) const;
|
|
size_t ItersPerTemporalSample() const;
|
|
eProcessState ProcessState() const;
|
|
eProcessAction ProcessAction() const;
|
|
EmberStats Stats() const;
|
|
|
|
//Non-virtual render getters and setters.
|
|
bool LockAccum() const;
|
|
void LockAccum(bool lockAccum);
|
|
bool EarlyClip() const;
|
|
void EarlyClip(bool earlyClip);
|
|
bool YAxisUp() const;
|
|
void YAxisUp(bool yup);
|
|
bool InsertPalette() const;
|
|
void InsertPalette(bool insertPalette);
|
|
bool ReclaimOnResize() const;
|
|
void ReclaimOnResize(bool reclaimOnResize);
|
|
void Callback(RenderCallback* callback);
|
|
void ThreadCount(size_t threads, const char* seedString = nullptr);
|
|
size_t BytesPerChannel() const;
|
|
size_t NumChannels() const;
|
|
eThreadPriority Priority() const;
|
|
void Priority(eThreadPriority priority);
|
|
eInteractiveFilter InteractiveFilter() const;
|
|
void InteractiveFilter(eInteractiveFilter filter);
|
|
|
|
//Virtual render properties, getters and setters.
|
|
virtual size_t ThreadCount() const;
|
|
virtual eRendererType RendererType() const;
|
|
virtual bool Shared() const;
|
|
|
|
//Abstract render properties, getters only.
|
|
virtual size_t TemporalSamples() const = 0;
|
|
virtual size_t HistBucketSize() const = 0;
|
|
virtual size_t FinalRasW() const = 0;
|
|
virtual size_t FinalRasH() const = 0;
|
|
virtual size_t SubBatchSize() const = 0;
|
|
virtual size_t FuseCount() const = 0;
|
|
virtual double ScaledQuality() const = 0;
|
|
virtual double LowerLeftX(bool gutter = true) const = 0;
|
|
virtual double LowerLeftY(bool gutter = true) const = 0;
|
|
virtual double UpperRightX(bool gutter = true) const = 0;
|
|
virtual double UpperRightY(bool gutter = true) const = 0;
|
|
|
|
//Non-virtual threading control.
|
|
void Reset();
|
|
void EnterRender();
|
|
void LeaveRender();
|
|
void EnterFinalAccum();
|
|
void LeaveFinalAccum();
|
|
void EnterResize();
|
|
void LeaveResize();
|
|
void Abort();
|
|
bool Aborted();
|
|
void Pause(bool pause);
|
|
bool Paused();
|
|
bool InRender();
|
|
bool InFinalAccum();
|
|
|
|
void* m_ProgressParameter = nullptr;
|
|
protected:
|
|
bool m_EarlyClip = false;
|
|
bool m_YAxisUp = false;
|
|
bool m_LockAccum = false;
|
|
bool m_InRender = false;
|
|
bool m_InFinalAccum = false;
|
|
bool m_InsertPalette = false;
|
|
bool m_ReclaimOnResize = false;
|
|
bool m_CurvesSet = false;
|
|
volatile bool m_Abort = false;
|
|
volatile bool m_Pause = false;
|
|
size_t m_SuperRasW;
|
|
size_t m_SuperRasH;
|
|
size_t m_SuperSize = 0;
|
|
size_t m_GutterWidth;
|
|
size_t m_DensityFilterOffset;
|
|
size_t m_NumChannels = 4;
|
|
size_t m_BytesPerChannel = 4;
|
|
size_t m_ThreadsToUse;
|
|
size_t m_VibGamCount;
|
|
size_t m_LastTemporalSample = 0;
|
|
size_t m_LastIter = 0;
|
|
double m_LastIterPercent = 0;
|
|
eThreadPriority m_Priority = eThreadPriority::NORMAL;
|
|
eProcessAction m_ProcessAction = eProcessAction::FULL_RENDER;
|
|
eProcessState m_ProcessState = eProcessState::NONE;
|
|
eInteractiveFilter m_InteractiveFilter = eInteractiveFilter::FILTER_LOG;
|
|
EmberStats m_Stats;
|
|
RenderCallback* m_Callback = nullptr;
|
|
vector<size_t> m_SubBatch;
|
|
vector<size_t> m_BadVals;
|
|
vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>> m_Rand;
|
|
std::recursive_mutex m_RenderingCs, m_AccumCs, m_FinalAccumCs, m_ResizeCs;
|
|
Timing m_RenderTimer, m_IterTimer, m_ProgressTimer;
|
|
};
|
|
}
|