diff options
| author | Markus Wick <degasus@users.noreply.github.com> | 2016-10-08 00:54:36 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-10-08 00:54:36 +0200 |
| commit | a172bd7d8cac3c417e33ba8fafb89963fc8b5bbd (patch) | |
| tree | 5b650dbbd073c0d43ca4eba4301705f31da28f85 /Source/Core/VideoCommon | |
| parent | 5e027a0817c4577539fc969c3cd7900553b3fb99 (diff) | |
| parent | 8c999f9ee801116e723381432b96d8a9ae6ddc68 (diff) | |
Merge pull request #4318 from degasus/framedump
Renderer: Move framedumping logic to VideoCommon.
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/RenderBase.cpp | 96 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/RenderBase.h | 19 |
2 files changed, 103 insertions, 12 deletions
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 60375a43db..1dd07c905b 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -20,6 +20,7 @@ #include "Common/CommonTypes.h" #include "Common/Event.h" +#include "Common/FileUtil.h" #include "Common/Flag.h" #include "Common/Profiler.h" #include "Common/StringUtil.h" @@ -97,14 +98,10 @@ static float AspectToWidescreen(float aspect) return aspect * ((16.0f / 9.0f) / (4.0f / 3.0f)); } -Renderer::Renderer() : frame_data(), bLastFrameDumped(false) +Renderer::Renderer() { UpdateActiveConfig(); TextureCacheBase::OnConfigChanged(g_ActiveConfig); - -#if defined _WIN32 || defined HAVE_LIBAV - bAVIDumping = false; -#endif } Renderer::~Renderer() @@ -113,9 +110,14 @@ Renderer::~Renderer() prev_efb_format = PEControl::INVALID_FMT; efb_scale_numeratorX = efb_scale_numeratorY = efb_scale_denominatorX = efb_scale_denominatorY = 1; -#if defined _WIN32 || defined HAVE_LIBAV - if (SConfig::GetInstance().m_DumpFrames && bLastFrameDumped && bAVIDumping) + +#if defined(HAVE_LIBAV) || defined(_WIN32) + // Stop frame dumping if it was left enabled at shutdown time. + if (m_AVI_dumping) + { AVIDump::Stop(); + m_AVI_dumping = false; + } #endif } @@ -534,6 +536,86 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const XFBWrited = false; } +bool Renderer::IsFrameDumping() +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (SConfig::GetInstance().m_DumpFrames) + return true; + + if (m_last_frame_dumped && m_AVI_dumping) + { + AVIDump::Stop(); + std::vector<u8>().swap(m_frame_data); + m_last_framedump_width = m_last_framedump_height = 0; + m_AVI_dumping = false; + OSD::AddMessage("Stop dumping frames", 2000); + } + m_last_frame_dumped = false; +#endif + return false; +} + +void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format, + bool swap_upside_down) +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (w == 0 || h == 0) + return; + + size_t image_size; + switch (format) + { + case AVIDump::DumpFormat::FORMAT_BGR: + image_size = 3 * w * h; + break; + case AVIDump::DumpFormat::FORMAT_RGBA: + image_size = 4 * w * h; + break; + } + + m_last_framedump_width = w; + m_last_framedump_height = h; + m_last_framedump_format = format; + + // TODO: Refactor this. Right now it's needed for the implace flipping of the image. + // It's also used to repeat the last frame. + m_frame_data.assign(data, data + image_size); + + if (!m_last_frame_dumped) + { + m_AVI_dumping = AVIDump::Start(w, h, format); + if (!m_AVI_dumping) + { + OSD::AddMessage("AVIDump Start failed", 2000); + } + else + { + OSD::AddMessage(StringFromFormat("Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", + File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), w, h), + 2000); + } + } + if (m_AVI_dumping) + { + if (swap_upside_down) + FlipImageData(m_frame_data.data(), w, h, 4); + AVIDump::AddFrame(m_frame_data.data(), w, h); + } + + m_last_frame_dumped = true; +#endif +} + +void Renderer::RepeatFrameDumpFrame() +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (SConfig::GetInstance().m_DumpFrames && m_AVI_dumping && !m_frame_data.empty()) + { + AVIDump::AddFrame(m_frame_data.data(), m_last_framedump_width, m_last_framedump_height); + } +#endif +} + void Renderer::FlipImageData(u8* data, int w, int h, int pixel_width) { for (int y = 0; y < h / 2; ++y) diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 584c8dbec6..1f648bb17b 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -23,6 +23,7 @@ #include "Common/Event.h" #include "Common/Flag.h" #include "Common/MathUtil.h" +#include "VideoCommon/AVIDump.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/FPSCounter.h" #include "VideoCommon/VideoBackendBase.h" @@ -146,15 +147,15 @@ protected: static void CheckFifoRecording(); static void RecordVideoMemory(); + bool IsFrameDumping(); + void DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format, + bool swap_upside_down = false); + void RepeatFrameDumpFrame(); + static volatile bool s_bScreenshot; static std::mutex s_criticalScreenshot; static std::string s_sScreenshotName; - bool bAVIDumping; - - std::vector<u8> frame_data; - bool bLastFrameDumped; - // The framebuffer size static int s_target_width; static int s_target_height; @@ -186,6 +187,14 @@ private: static unsigned int efb_scale_numeratorY; static unsigned int efb_scale_denominatorX; static unsigned int efb_scale_denominatorY; + + // framedumping + std::vector<u8> m_frame_data; + bool m_AVI_dumping = false; + bool m_last_frame_dumped = false; + int m_last_framedump_width = 0; + int m_last_framedump_height = 0; + AVIDump::DumpFormat m_last_framedump_format; }; extern std::unique_ptr<Renderer> g_renderer; |
