--Bug fixes

-Stop rendering process when a single render or save fails.
This commit is contained in:
Person 2023-11-04 19:02:22 -06:00
parent 99d1096b51
commit 1a1cb8b0f2
4 changed files with 31 additions and 20 deletions

View File

@ -116,7 +116,8 @@ static bool WriteJpeg(const char* filename, unsigned char* image, size_t width,
jpeg_destroy_compress(&info); jpeg_destroy_compress(&info);
if (file != nullptr) if (file != nullptr)
fclose(file); if (fclose(file))//Non-zero indicates failure.
return false;
b = true; b = true;
} }
@ -225,7 +226,8 @@ static bool WritePng(const char* filename, unsigned char* image, size_t width, s
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
if (file != nullptr) if (file != nullptr)
fclose(file); if (fclose(file))
return false;
b = true; b = true;
} }

View File

@ -107,6 +107,7 @@ bool FinalRenderEmberController<T>::RenderSingleEmber(Ember<T>& ember, bool full
return false; return false;
} }
auto ret = true;
ember.m_TemporalSamples = 1;//No temporal sampling. ember.m_TemporalSamples = 1;//No temporal sampling.
m_Renderer->SetEmber(ember, fullRender ? eProcessAction::FULL_RENDER : eProcessAction::KEEP_ITERATING, /* updatePointer */ true); m_Renderer->SetEmber(ember, fullRender ? eProcessAction::FULL_RENDER : eProcessAction::KEEP_ITERATING, /* updatePointer */ true);
m_Renderer->PrepFinalAccumVector(m_FinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run(). m_Renderer->PrepFinalAccumVector(m_FinalImage);//Must manually call this first because it could be erroneously made smaller due to strips if called inside Renderer::Run().
@ -119,15 +120,19 @@ bool FinalRenderEmberController<T>::RenderSingleEmber(Ember<T>& ember, bool full
{ {
Output("Rendering failed.\n"); Output("Rendering failed.\n");
m_Fractorium->ErrorReportToQTextEdit(m_Renderer->ErrorReport(), m_FinalRenderDialog->ui.FinalRenderTextOutput, false);//Internally calls invoke. m_Fractorium->ErrorReportToQTextEdit(m_Renderer->ErrorReport(), m_FinalRenderDialog->ui.FinalRenderTextOutput, false);//Internally calls invoke.
ret = false;
}, },
[&](Ember<T>& finalEmber) [&](Ember<T>& finalEmber)
{ {
m_FinishedImageCount.fetch_add(1); m_FinishedImageCount.fetch_add(1);
SaveCurrentRender(finalEmber);
if (SaveCurrentRender(finalEmber) == "")
m_Run = ret = false;
RenderComplete(finalEmber); RenderComplete(finalEmber);
HandleFinishedProgress(); HandleFinishedProgress();
});//Final strip. });//Final strip.
return true; return ret;
} }
/// <summary> /// <summary>
@ -188,13 +193,14 @@ bool FinalRenderEmberController<T>::RenderSingleEmberFromSeries(std::atomic<size
comments = renderer->ImageComments(stats, 0, true); comments = renderer->ImageComments(stats, 0, true);
writeThread = std::thread([&](size_t tempTime, size_t threadFinalImageIndex) writeThread = std::thread([&](size_t tempTime, size_t threadFinalImageIndex)
{ {
SaveCurrentRender(*m_EmberFile.Get(tempTime), if (SaveCurrentRender(*m_EmberFile.Get(tempTime),
comments,//These all don't change during the renders, so it's ok to access them in the thread. comments,//These all don't change during the renders, so it's ok to access them in the thread.
finalImages[threadFinalImageIndex], finalImages[threadFinalImageIndex],
renderer->FinalRasW(), renderer->FinalRasW(),
renderer->FinalRasH(), renderer->FinalRasH(),
m_FinalRenderDialog->Png16Bit(), m_FinalRenderDialog->Png16Bit(),
m_FinalRenderDialog->Transparency()); m_FinalRenderDialog->Transparency()) == "")
m_Run = false;
}, ftime, finalImageIndex); }, ftime, finalImageIndex);
m_FinishedImageCount.fetch_add(1); m_FinishedImageCount.fetch_add(1);
RenderComplete(*m_EmberFile.Get(ftime), stats, renderTimer); RenderComplete(*m_EmberFile.Get(ftime), stats, renderTimer);
@ -336,7 +342,8 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
Output("No renderer present, aborting."); Output("No renderer present, aborting.");
} }
const QString totalTimeString = "All renders completed in: " + QString::fromStdString(m_TotalTimer.Format(m_TotalTimer.Toc())) + "."; const QString totalTimeString = m_Run ? "All renders completed in: " + QString::fromStdString(m_TotalTimer.Format(m_TotalTimer.Toc())) + "."
: "Render aborted.";
Output(totalTimeString); Output(totalTimeString);
QFile::remove(backup); QFile::remove(backup);
QMetaObject::invokeMethod(m_FinalRenderDialog, "Pause", Qt::QueuedConnection, Q_ARG(bool, false)); QMetaObject::invokeMethod(m_FinalRenderDialog, "Pause", Qt::QueuedConnection, Q_ARG(bool, false));
@ -856,13 +863,12 @@ QString FinalRenderEmberController<T>::SaveCurrentRender(Ember<T>& ember)
/// <param name="height">The height in pixels of the image</param> /// <param name="height">The height in pixels of the image</param>
/// <param name="png16Bit">Whether to use 16 bits per channel per pixel when saving as Png/32-bits per channel when saving as Exr.</param> /// <param name="png16Bit">Whether to use 16 bits per channel per pixel when saving as Png/32-bits per channel when saving as Exr.</param>
/// <param name="transparency">Whether to use alpha when saving as Png or Exr.</param> /// <param name="transparency">Whether to use alpha when saving as Png or Exr.</param>
/// <returns>The full path and filename the image was saved to.</returns> /// <returns>The full path and filename the image was saved to. Empty string is saving failed.</returns>
template<typename T> template<typename T>
QString FinalRenderEmberController<T>::SaveCurrentRender(Ember<T>& ember, const EmberImageComments& comments, vector<v4F>& pixels, size_t width, size_t height, bool png16Bit, bool transparency) QString FinalRenderEmberController<T>::SaveCurrentRender(Ember<T>& ember, const EmberImageComments& comments, vector<v4F>& pixels, size_t width, size_t height, bool png16Bit, bool transparency)
{ {
const auto filename = ComposePath(QString::fromStdString(ember.m_Name)); const auto filename = ComposePath(QString::fromStdString(ember.m_Name));
FractoriumEmberControllerBase::SaveCurrentRender(filename, comments, pixels, width, height, png16Bit, transparency); return FractoriumEmberControllerBase::SaveCurrentRender(filename, comments, pixels, width, height, png16Bit, transparency) ? filename : "";
return filename;
} }
/// <summary> /// <summary>

View File

@ -285,7 +285,7 @@ public:
void ClearFinalImages(); void ClearFinalImages();
void Shutdown(); void Shutdown();
void UpdateRender(eProcessAction action = eProcessAction::FULL_RENDER); void UpdateRender(eProcessAction action = eProcessAction::FULL_RENDER);
void SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<v4F>& pixels, size_t width, size_t height, bool png16Bit, bool transparency); bool SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<v4F>& pixels, size_t width, size_t height, bool png16Bit, bool transparency);
RendererBase* Renderer() { return m_Renderer.get(); } RendererBase* Renderer() { return m_Renderer.get(); }
vector<v4F>* FinalImage() { return &(m_FinalImage); } vector<v4F>* FinalImage() { return &(m_FinalImage); }
vector<v4F>* PreviewFinalImage() { return &m_PreviewFinalImage; } vector<v4F>* PreviewFinalImage() { return &m_PreviewFinalImage; }

View File

@ -120,11 +120,12 @@ void FractoriumEmberController<T>::DeleteRenderer()
/// <param name="height">The height in pixels of the image</param> /// <param name="height">The height in pixels of the image</param>
/// <param name="png16Bit">Whether to use 16 bits per channel per pixel when saving as Png/32-bits per channel when saving as Exr.</param> /// <param name="png16Bit">Whether to use 16 bits per channel per pixel when saving as Png/32-bits per channel when saving as Exr.</param>
/// <param name="transparency">Whether to use alpha when saving as Png or Exr.</param> /// <param name="transparency">Whether to use alpha when saving as Png or Exr.</param>
void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<v4F>& pixels, size_t width, size_t height, bool png16Bit, bool transparency) bool FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, const EmberImageComments& comments, vector<v4F>& pixels, size_t width, size_t height, bool png16Bit, bool transparency)
{ {
bool ret = false;
if (filename != "") if (filename != "")
{ {
bool ret = false;
const auto size = width * height; const auto size = width * height;
auto settings = m_Fractorium->m_Settings; auto settings = m_Fractorium->m_Settings;
QFileInfo fileInfo(filename); QFileInfo fileInfo(filename);
@ -138,7 +139,7 @@ void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, c
if (pixels.size() < size) if (pixels.size() < size)
{ {
m_Fractorium->ShowCritical("Save Failed", "Dimensions didn't match, not saving.", true); m_Fractorium->ShowCritical("Save Failed", "Dimensions didn't match, not saving.", true);
return; return ret;
} }
auto data = pixels.data(); auto data = pixels.data();
@ -189,7 +190,7 @@ void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, c
else else
{ {
m_Fractorium->ShowCritical("Save Failed", "Unrecognized format " + suffix + ", not saving.", true); m_Fractorium->ShowCritical("Save Failed", "Unrecognized format " + suffix + ", not saving.", true);
return; return ret;
} }
if (ret) if (ret)
@ -197,6 +198,8 @@ void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, c
else else
m_Fractorium->ShowCritical("Save Failed", "Could not save file, try saving to a different folder.", true); m_Fractorium->ShowCritical("Save Failed", "Could not save file, try saving to a different folder.", true);
} }
return ret;
} }
/// <summary> /// <summary>