summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/RenderBase.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2016-11-18 22:57:08 +1000
committerStenzek <stenzek@gmail.com>2016-11-23 12:07:49 +1000
commit6d0b9b816fd44666f31d5cd0435b2b40375a7e85 (patch)
tree0f327894744d3aa33a3131bd44f72cbf8681abc6 /Source/Core/VideoCommon/RenderBase.cpp
parentb6f9bdf16bf29a49c6fcf12b07f144d2ccbabbba (diff)
VideoCommon: Support dumping frames to images
This is mainly for potential Android fifoci usage, and thus is not exposed anywhere in the UI. To enable, set DumpFramesAsImages under Settings in GFX.ini.
Diffstat (limited to 'Source/Core/VideoCommon/RenderBase.cpp')
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp114
1 files changed, 98 insertions, 16 deletions
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index 623ac973ad..3120083e56 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -22,6 +22,8 @@
#include "Common/Event.h"
#include "Common/FileUtil.h"
#include "Common/Flag.h"
+#include "Common/Logging/Log.h"
+#include "Common/MsgHandler.h"
#include "Common/Profiler.h"
#include "Common/StringUtil.h"
#include "Common/Thread.h"
@@ -696,8 +698,18 @@ void Renderer::FinishFrameData()
void Renderer::RunFrameDumps()
{
Common::SetCurrentThreadName("FrameDumping");
- bool avi_dump_started = false;
- std::vector<u8> data;
+ bool dump_to_avi = !g_ActiveConfig.bDumpFramesAsImages;
+ bool frame_dump_started = false;
+
+// If Dolphin was compiled without libav, we only support dumping to images.
+#if !defined(HAVE_LIBAV) && !defined(_WIN32)
+ if (dump_to_avi)
+ {
+ WARN_LOG(VIDEO, "AVI frame dump requested, but Dolphin was compiled without libav. "
+ "Frame dump will be saved as images instead.");
+ dump_to_avi = false;
+ }
+#endif
while (true)
{
@@ -727,33 +739,103 @@ void Renderer::RunFrameDumps()
s_screenshotCompleted.Set();
}
-#if defined(HAVE_LIBAV) || defined(_WIN32)
if (SConfig::GetInstance().m_DumpFrames)
{
- if (!avi_dump_started)
+ if (!frame_dump_started)
{
- if (AVIDump::Start(config.width, config.height))
- {
- avi_dump_started = true;
- }
+ if (dump_to_avi)
+ frame_dump_started = StartFrameDumpToAVI(config);
else
- {
+ frame_dump_started = StartFrameDumpToImage(config);
+
+ // Stop frame dumping if we fail to start.
+ if (!frame_dump_started)
SConfig::GetInstance().m_DumpFrames = false;
- }
}
- AVIDump::AddFrame(config.data, config.width, config.height, config.stride, config.state);
+ // If we failed to start frame dumping, don't write a frame.
+ if (frame_dump_started)
+ {
+ if (dump_to_avi)
+ DumpFrameToAVI(config);
+ else
+ DumpFrameToImage(config);
+ }
}
-#endif
m_frame_dump_done.Set();
}
+ if (frame_dump_started)
+ {
+ // No additional cleanup is needed when dumping to images.
+ if (dump_to_avi)
+ StopFrameDumpToAVI();
+ }
+}
+
#if defined(HAVE_LIBAV) || defined(_WIN32)
- if (avi_dump_started)
+
+bool Renderer::StartFrameDumpToAVI(const FrameDumpConfig& config)
+{
+ return AVIDump::Start(config.width, config.height);
+}
+
+void Renderer::DumpFrameToAVI(const FrameDumpConfig& config)
+{
+ AVIDump::AddFrame(config.data, config.width, config.height, config.stride, config.state);
+}
+
+void Renderer::StopFrameDumpToAVI()
+{
+ AVIDump::Stop();
+}
+
+#else
+
+bool Renderer::StartFrameDumpToAVI(const FrameDumpConfig& config)
+{
+ return false;
+}
+
+void Renderer::DumpFrameToAVI(const FrameDumpConfig& config)
+{
+}
+
+void Renderer::StopFrameDumpToAVI()
+{
+}
+
+#endif // defined(HAVE_LIBAV) || defined(WIN32)
+
+std::string Renderer::GetFrameDumpNextImageFileName() const
+{
+ return StringFromFormat("%sframedump_%u.png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
+ m_frame_dump_image_counter);
+}
+
+bool Renderer::StartFrameDumpToImage(const FrameDumpConfig& config)
+{
+ m_frame_dump_image_counter = 1;
+ if (!SConfig::GetInstance().m_DumpFramesSilent)
{
- avi_dump_started = false;
- AVIDump::Stop();
+ // Only check for the presence of the first image to confirm overwriting.
+ // A previous run will always have at least one image, and it's safe to assume that if the user
+ // has allowed the first image to be overwritten, this will apply any remaining images as well.
+ std::string filename = GetFrameDumpNextImageFileName();
+ if (File::Exists(filename))
+ {
+ if (!AskYesNoT("Frame dump image(s) '%s' already exists. Overwrite?", filename.c_str()))
+ return false;
+ }
}
-#endif
+
+ return true;
+}
+
+void Renderer::DumpFrameToImage(const FrameDumpConfig& config)
+{
+ std::string filename = GetFrameDumpNextImageFileName();
+ TextureToPng(config.data, config.stride, filename, config.width, config.height, false);
+ m_frame_dump_image_counter++;
}