mirror of
				https://bitbucket.org/mfeemster/fractorium.git
				synced 2025-10-31 01:10:24 -04:00 
			
		
		
		
	--User changes
-Allow for pausing and resuming of final renders. --Code changes -Only instantiate float version of Palette and PaletteList, no need for double since it's never used. -Allow for FinalRenderDialog to be queried on whether it's currently rendering.
This commit is contained in:
		| @ -62,8 +62,6 @@ uint Timing::m_ProcessorCount; | ||||
| 	template<> vector<pair<pair<string, string>, vector<string>>> XmlToEmber<T>::m_BadVariationNames = vector<pair<pair<string, string>, vector<string>>>(); \ | ||||
| 	template EMBER_API class Point<T>; \ | ||||
| 	template EMBER_API struct Color<T>; \ | ||||
| 	template EMBER_API class Palette<T>; \ | ||||
| 	template EMBER_API class PaletteList<T>; \ | ||||
| 	template EMBER_API class Iterator<T>; \ | ||||
| 	template EMBER_API class StandardIterator<T>; \ | ||||
| 	template EMBER_API class XaosIterator<T>; \ | ||||
| @ -457,6 +455,10 @@ uint Timing::m_ProcessorCount; | ||||
| EXPORT_SINGLE_TYPE_EMBER(float) | ||||
| EXPORT_TWO_TYPE_EMBER(float, float) | ||||
|  | ||||
| //Only ever use float palettes. | ||||
| template EMBER_API class Palette<float>; | ||||
| template EMBER_API class PaletteList<float>; | ||||
|  | ||||
| #ifdef DO_DOUBLE | ||||
| 	EXPORT_SINGLE_TYPE_EMBER(double) | ||||
| 	EXPORT_TWO_TYPE_EMBER(double, float) | ||||
|  | ||||
| @ -1287,6 +1287,11 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample | ||||
| 			m_Samples[threadIndex][0].m_Y = m_Rand[threadIndex].template Frand11<T>(); | ||||
| 			m_Samples[threadIndex][0].m_Z = 0;//m_Ember.m_CamZPos;//Apo set this to 0, then made the user use special variations to kick it. It seems easier to just set it to zpos. | ||||
| 			m_Samples[threadIndex][0].m_ColorX = m_Rand[threadIndex].template Frand01<T>(); | ||||
|  | ||||
| 			//Check if the user wanted to suspend the process. | ||||
| 			while (Paused()) | ||||
| 				std::this_thread::sleep_for(500ms); | ||||
|  | ||||
| 			//Finally, iterate. | ||||
| 			//t.Tic(); | ||||
| 			//Iterating, loop 3. | ||||
|  | ||||
| @ -541,9 +541,12 @@ void RendererBase::LeaveFinalAccum() { m_FinalAccumCs.unlock(); m_InFinalAccum = | ||||
| void RendererBase::EnterResize() { m_ResizeCs.lock(); } | ||||
| void RendererBase::LeaveResize() { m_ResizeCs.unlock(); } | ||||
|  | ||||
| void RendererBase::Abort()   { m_Abort = true; } | ||||
| void RendererBase::Abort() { m_Abort = true; Pause(false); } | ||||
| bool RendererBase::Aborted() { return m_Abort; } | ||||
|  | ||||
| void RendererBase::Pause(bool pause) { m_Pause = pause; } | ||||
| bool RendererBase::Paused() { return m_Pause; } | ||||
|  | ||||
| bool RendererBase::InRender()	  { return m_InRender; } | ||||
| bool RendererBase::InFinalAccum() { return m_InFinalAccum; } | ||||
|  | ||||
|  | ||||
| @ -188,6 +188,8 @@ public: | ||||
| 	void LeaveResize(); | ||||
| 	void Abort(); | ||||
| 	bool Aborted(); | ||||
| 	void Pause(bool pause); | ||||
| 	bool Paused(); | ||||
| 	bool InRender(); | ||||
| 	bool InFinalAccum(); | ||||
|  | ||||
| @ -203,6 +205,7 @@ protected: | ||||
| 	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; | ||||
|  | ||||
| @ -71,7 +71,8 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(QWidget* p, Qt::WindowF | ||||
| 	connect(m_PrefixEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnPrefixChanged(const QString&)), Qt::QueuedConnection); | ||||
| 	connect(m_SuffixEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnSuffixChanged(const QString&)), Qt::QueuedConnection); | ||||
| 	ui.FinalRenderStartButton->disconnect(SIGNAL(clicked(bool))); | ||||
| 	connect(ui.FinalRenderStartButton, SIGNAL(clicked(bool)), this, SLOT(OnRenderClicked(bool)),		  Qt::QueuedConnection); | ||||
| 	connect(ui.FinalRenderStartButton, SIGNAL(clicked(bool)), this, SLOT(OnRenderClicked(bool)),	   Qt::QueuedConnection); | ||||
| 	connect(ui.FinalRenderPauseButton, SIGNAL(clicked(bool)), this, SLOT(OnPauseClicked(bool)),		   Qt::QueuedConnection); | ||||
| 	connect(ui.FinalRenderStopButton,  SIGNAL(clicked(bool)), this, SLOT(OnCancelRenderClicked(bool)), Qt::QueuedConnection); | ||||
| 	table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); | ||||
| 	ui.FinalRenderSizeTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); | ||||
| @ -205,6 +206,7 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(QWidget* p, Qt::WindowF | ||||
| 	w = SetTabOrder(this, w, m_SuffixEdit); | ||||
| 	w = SetTabOrder(this, w, ui.FinalRenderTextOutput); | ||||
| 	w = SetTabOrder(this, w, ui.FinalRenderStartButton); | ||||
| 	w = SetTabOrder(this, w, ui.FinalRenderPauseButton); | ||||
| 	w = SetTabOrder(this, w, ui.FinalRenderStopButton); | ||||
| 	w = SetTabOrder(this, w, ui.FinalRenderCloseButton); | ||||
| } | ||||
| @ -652,7 +654,21 @@ void FractoriumFinalRenderDialog::OnSuffixChanged(const QString& s) | ||||
| void FractoriumFinalRenderDialog::OnRenderClicked(bool checked) | ||||
| { | ||||
| 	if (CreateControllerFromGUI(true)) | ||||
| 	{ | ||||
| 		Pause(false); | ||||
| 		m_Controller->Render(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Pause or resume the render process. | ||||
| /// </summary> | ||||
| /// <param name="checked">Ignored</param> | ||||
| void FractoriumFinalRenderDialog::OnPauseClicked(bool checked) | ||||
| { | ||||
| 	if (m_Controller.get()) | ||||
| 		if (m_Controller->Running()) | ||||
| 			Pause(!m_Controller->Paused()); | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| @ -662,7 +678,28 @@ void FractoriumFinalRenderDialog::OnRenderClicked(bool checked) | ||||
| void FractoriumFinalRenderDialog::OnCancelRenderClicked(bool checked) | ||||
| { | ||||
| 	if (m_Controller.get()) | ||||
| 	{ | ||||
| 		Pause(false); | ||||
| 		m_Controller->CancelRender(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Pause or resume the render process. | ||||
| /// </summary> | ||||
| /// <param name="checked">True to pause, else resume.</param> | ||||
| void FractoriumFinalRenderDialog::Pause(bool paused) | ||||
| { | ||||
| 	if (paused) | ||||
| 	{ | ||||
| 		m_Controller->Pause(true); | ||||
| 		ui.FinalRenderPauseButton->setText("Resume"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		m_Controller->Pause(false); | ||||
| 		ui.FinalRenderPauseButton->setText("Pause"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
|  | ||||
| @ -109,7 +109,9 @@ public slots: | ||||
| 	void OnPrefixChanged(const QString& s); | ||||
| 	void OnSuffixChanged(const QString& s); | ||||
| 	void OnRenderClicked(bool checked); | ||||
| 	void OnPauseClicked(bool checked); | ||||
| 	void OnCancelRenderClicked(bool checked); | ||||
| 	void Pause(bool paused); | ||||
| 	virtual void reject() override; | ||||
|  | ||||
| protected: | ||||
|  | ||||
| @ -1153,6 +1153,22 @@ | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="FinalRenderPauseButton"> | ||||
|            <property name="enabled"> | ||||
|             <bool>true</bool> | ||||
|            </property> | ||||
|            <property name="focusPolicy"> | ||||
|             <enum>Qt::TabFocus</enum> | ||||
|            </property> | ||||
|            <property name="text"> | ||||
|             <string>Pause</string> | ||||
|            </property> | ||||
|            <property name="autoDefault"> | ||||
|             <bool>false</bool> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="FinalRenderStopButton"> | ||||
|            <property name="focusPolicy"> | ||||
|  | ||||
| @ -28,7 +28,6 @@ void FinalRenderEmberController<T>::CancelRender() | ||||
| { | ||||
| 	if (m_Result.isRunning()) | ||||
| 	{ | ||||
| 		//tbb::task_group g; | ||||
| 		std::thread th([&] | ||||
| 		{ | ||||
| 			m_Run = false; | ||||
| @ -123,6 +122,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD | ||||
| 			m_XmlWriter.Save(backup.toStdString().c_str(), *m_Ember, 0, true, false, true, false, false); | ||||
|  | ||||
| 		m_FinishedImageCount.store(0); | ||||
| 		Pause(false); | ||||
| 		SyncGuiToRenderer(); | ||||
| 		FirstOrDefaultRenderer()->m_ProgressParameter = reinterpret_cast<void*>(¤tStripForProgress);//When animating, only the first (primary) device has a progress parameter. | ||||
| 		m_GuiState.m_Strips = VerifyStrips(m_Ember->m_FinalRasH, m_GuiState.m_Strips, | ||||
| @ -324,6 +324,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD | ||||
| 		QString totalTimeString = "All renders completed in: " + QString::fromStdString(m_TotalTimer.Format(m_TotalTimer.Toc())) + "."; | ||||
| 		Output(totalTimeString); | ||||
| 		QFile::remove(backup); | ||||
| 		QMetaObject::invokeMethod(m_FinalRenderDialog, "Pause", Qt::QueuedConnection, Q_ARG(bool, false)); | ||||
| 		m_Run = false; | ||||
| 	}; | ||||
| } | ||||
| @ -730,6 +731,46 @@ void FinalRenderEmberController<T>::RenderComplete(Ember<T>& ember) | ||||
| 		RenderComplete(ember, m_Stats, m_RenderTimer); | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Pause or resume the renderer(s). | ||||
| /// </summary> | ||||
| /// <param name="pause">True to pause, false to unpause.</param> | ||||
| template<typename T> | ||||
| void FinalRenderEmberController<T>::Pause(bool pause) | ||||
| { | ||||
| 	if (m_Renderer.get()) | ||||
| 	{ | ||||
| 		m_Renderer->Pause(pause); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		for (auto& r : m_Renderers) | ||||
| 			r->Pause(pause); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Retrieve the paused state of the renderer(s). | ||||
| /// </summary> | ||||
| /// <returns>True if the renderer(s) is paused, else false.</returns> | ||||
| template<typename T> | ||||
| bool FinalRenderEmberController<T>::Paused() | ||||
| { | ||||
| 	if (m_Renderer.get()) | ||||
| 	{ | ||||
| 		return m_Renderer->Paused(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		bool b = !m_Renderers.empty(); | ||||
|  | ||||
| 		for (auto& r : m_Renderers) | ||||
| 			b &= r->Paused(); | ||||
|  | ||||
| 		return b; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Handle setting the appropriate progress bar values when an image render has finished. | ||||
| /// This handles single image, animations, and strips. | ||||
|  | ||||
| @ -71,6 +71,7 @@ public: | ||||
| 	virtual void CancelRender() { } | ||||
| 	virtual QString CheckMemory(const tuple<size_t, size_t, size_t>& p) { return ""; } | ||||
|  | ||||
| 	bool Running() { return m_Result.isRunning(); } | ||||
| 	bool CreateRendererFromGUI(); | ||||
| 	void Output(const QString& s); | ||||
|  | ||||
| @ -133,6 +134,8 @@ public: | ||||
| 	EmberNs::Renderer<T, float>* FirstOrDefaultRenderer(); | ||||
|  | ||||
| protected: | ||||
| 	virtual void Pause(bool pause) override; | ||||
| 	virtual bool Paused() override; | ||||
| 	void HandleFinishedProgress(); | ||||
| 	void SaveCurrentRender(Ember<T>& ember); | ||||
| 	void SaveCurrentRender(Ember<T>& ember, const EmberImageComments& comments, vector<v4F>& pixels, size_t width, size_t height, bool png16Bit, bool transparency); | ||||
|  | ||||
| @ -32,6 +32,24 @@ FractoriumEmberControllerBase::~FractoriumEmberControllerBase() | ||||
| 	m_RenderRestartTimer->stop(); | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Pause or resume the renderer. | ||||
| /// </summary> | ||||
| /// <param name="pause">True to pause, false to unpause.</param> | ||||
| void FractoriumEmberControllerBase::Pause(bool pause) | ||||
| { | ||||
| 	m_Renderer->Pause(pause); | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Retrieve the paused state of the renderer. | ||||
| /// </summary> | ||||
| /// <returns>True if the renderer is paused, else false.</returns> | ||||
| bool FractoriumEmberControllerBase::Paused() | ||||
| { | ||||
| 	return m_Renderer->Paused(); | ||||
| } | ||||
|  | ||||
| /// <summary> | ||||
| /// Constructor which passes the main window parameter to the base, initializes the templated members contained in this class. | ||||
| /// Then sets up the parts of the GUI that require templated Widgets, such as the variations tree and the palette table. | ||||
|  | ||||
| @ -245,6 +245,8 @@ public: | ||||
| 	virtual void ClearUndo() { } | ||||
| 	virtual void DeleteRenderer() { } | ||||
| 	virtual GLEmberControllerBase* GLController() { return nullptr; } | ||||
| 	virtual void Pause(bool pause); | ||||
| 	virtual bool Paused(); | ||||
| 	bool RenderTimerRunning(); | ||||
| 	void StartRenderTimer(); | ||||
| 	void DelayedStartRenderTimer(); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Person
					Person