#pragma once #include "FractoriumSettings.h" #include "FractoriumEmberController.h" /// /// FinalRenderEmberControllerBase and FinalRenderEmberController classes. /// /// /// FractoriumEmberController and Fractorium need each other, but each can't include the other. /// So Fractorium includes this file, and Fractorium is declared as a forward declaration here. /// class Fractorium; class FractoriumFinalRenderDialog; template class FinalRenderPreviewRenderer; /// /// Used to hold the options specified in the current state of the Gui for performing the final render. /// struct FinalRenderGuiState { bool m_EarlyClip; bool m_YAxisUp; bool m_AlphaChannel; bool m_Transparency; bool m_OpenCL; bool m_Double; bool m_SaveXml; bool m_DoAll; bool m_DoSequence; bool m_KeepAspect; eScaleType m_Scale; QString m_Path; QString m_Ext; QString m_Prefix; QString m_Suffix; QList m_Devices; uint m_ThreadCount; int m_ThreadPriority; double m_WidthScale; double m_HeightScale; double m_Quality; uint m_TemporalSamples; uint m_Supersample; size_t m_Strips; }; /// /// FinalRenderEmberControllerBase serves as a non-templated base class with virtual /// functions which will be overridden in a derived class that takes a template parameter. /// Although not meant to be used as an interactive renderer, it derives from FractoriumEmberControllerBase /// to access a few of its members to avoid having to redefine them here. /// class FinalRenderEmberControllerBase : public FractoriumEmberControllerBase { friend FractoriumFinalRenderDialog; public: FinalRenderEmberControllerBase(FractoriumFinalRenderDialog* finalRenderDialog); virtual ~FinalRenderEmberControllerBase() { } virtual void SyncCurrentToGui() { } virtual void SyncGuiToEmbers(size_t widthOverride = 0, size_t heightOverride = 0) { } virtual void SyncCurrentToSizeSpinners(bool scale, bool size) { } virtual void ResetProgress(bool total = true) { } virtual tuple SyncAndComputeMemory() { return tuple(0, 0, 0); } virtual double OriginalAspect() { return 1; } virtual QString ComposePath(const QString& name) { return ""; } virtual void CancelRender() { } virtual QString CheckMemory(const tuple& p) { return ""; } bool CreateRendererFromGUI(); void Output(const QString& s); protected: bool m_Run = false; size_t m_ImageCount = 0; std::atomic m_FinishedImageCount; QFuture m_Result; std::function m_FinalRenderFunc; shared_ptr m_Settings; FractoriumFinalRenderDialog* m_FinalRenderDialog; FinalRenderGuiState m_GuiState; std::recursive_mutex m_ProgressCs; Timing m_RenderTimer; Timing m_TotalTimer; }; /// /// Templated derived class which implements all interaction functionality between the embers /// of a specific template type and the final render dialog. /// template class FinalRenderEmberController : public FinalRenderEmberControllerBase { friend FinalRenderPreviewRenderer; public: FinalRenderEmberController(FractoriumFinalRenderDialog* finalRender); virtual ~FinalRenderEmberController() { } //Virtual functions overridden from FractoriumEmberControllerBase. virtual void SetEmberFile(const EmberFile& emberFile, bool move) override; virtual void CopyEmberFile(EmberFile& emberFile, bool sequence, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) override; #ifdef DO_DOUBLE virtual void SetEmberFile(const EmberFile& emberFile, bool move) override; virtual void CopyEmberFile(EmberFile& emberFile, bool sequence, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) override; #endif virtual void SetEmber(size_t index, bool verbatim) override; virtual bool Render() override; virtual bool CreateRenderer(eRendererType renderType, const vector>& devices, bool shared = true) override; virtual int ProgressFunc(Ember& ember, void* foo, double fraction, int stage, double etaMs) override; virtual size_t Index() const override { return m_Ember->m_Index; } virtual uint SizeOfT() const override { return sizeof(T); } //Virtual functions overridden from FinalRenderEmberControllerBase. virtual void SyncCurrentToGui() override; virtual void SyncGuiToEmbers(size_t widthOverride = 0, size_t heightOverride = 0) override; virtual void SyncCurrentToSizeSpinners(bool scale, bool size) override; virtual void ResetProgress(bool total = true) override; virtual tuple SyncAndComputeMemory() override; virtual double OriginalAspect() override { return double(m_Ember->m_OrigFinalRasW) / m_Ember->m_OrigFinalRasH; } virtual QString Name() const override { return QString::fromStdString(m_Ember->m_Name); } virtual QString ComposePath(const QString& name) override; virtual void CancelRender() override; virtual QString CheckMemory(const tuple& p) override; //Non Virtual functions. EmberNs::Renderer* FirstOrDefaultRenderer(); protected: void HandleFinishedProgress(); void SaveCurrentRender(Ember& ember); void SaveCurrentRender(Ember& ember, const EmberImageComments& comments, vector& pixels, size_t width, size_t height, size_t channels, size_t bpc); void RenderComplete(Ember& ember); void RenderComplete(Ember& ember, const EmberStats& stats, Timing& renderTimer); void SyncGuiToEmber(Ember& ember, size_t widthOverride = 0, size_t heightOverride = 0); bool SyncGuiToRenderer(); void SetProgressComplete(int val); Ember* m_Ember; EmberFile m_EmberFile; EmberToXml m_XmlWriter; unique_ptr> m_FinalPreviewRenderer; vector>> m_Renderers; }; /// /// Thin derivation to handle preview rendering that is specific to the final render dialog. /// This differs from the preview renderers on the main window because they render multiple embers /// to a tree, whereas this renders a single preview. /// template class FinalRenderPreviewRenderer : public PreviewRenderer { public: using PreviewRenderer::m_PreviewRun; using PreviewRenderer::m_PreviewEmber; using PreviewRenderer::m_PreviewRenderer; using PreviewRenderer::m_PreviewFinalImage; FinalRenderPreviewRenderer(FinalRenderEmberController* controller) : m_Controller(controller) { } virtual void PreviewRenderFunc(uint start, uint end) override; private: FinalRenderEmberController* m_Controller; };