diff options
| author | Markus Wick <degasus@users.noreply.github.com> | 2016-11-08 11:01:40 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-11-08 11:01:40 +0100 |
| commit | 5378b6ab85122c246175e548991febc5786c31a9 (patch) | |
| tree | 53c359b0ea81565e104b39243ff0be7f4bd526c1 /Source/Core/VideoCommon/RenderBase.cpp | |
| parent | 363dec7bc7161215f32b4a1a16141d5c3509149c (diff) | |
| parent | a47332bf8a0f2b98a0b7043088d13d9fc0f44b30 (diff) | |
Merge pull request #4345 from degasus/framedump_threaded
Renderer: Threaded frame dumping.
Diffstat (limited to 'Source/Core/VideoCommon/RenderBase.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/RenderBase.cpp | 142 |
1 files changed, 94 insertions, 48 deletions
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 65f716ba9e..94d51ee481 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -24,6 +24,7 @@ #include "Common/Flag.h" #include "Common/Profiler.h" #include "Common/StringUtil.h" +#include "Common/Thread.h" #include "Common/Timer.h" #include "Core/ConfigManager.h" @@ -61,8 +62,7 @@ std::mutex Renderer::s_criticalScreenshot; std::string Renderer::s_sScreenshotName; Common::Event Renderer::s_screenshotCompleted; - -volatile bool Renderer::s_bScreenshot; +Common::Flag Renderer::s_screenshot; // The framebuffer size int Renderer::s_target_width; @@ -118,14 +118,9 @@ Renderer::~Renderer() efb_scale_numeratorX = efb_scale_numeratorY = efb_scale_denominatorX = efb_scale_denominatorY = 1; -#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 + ShutdownFrameDumping(); + if (m_frame_dump_thread.joinable()) + m_frame_dump_thread.join(); } void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight, @@ -307,7 +302,7 @@ void Renderer::SetScreenshot(const std::string& filename) { std::lock_guard<std::mutex> lk(s_criticalScreenshot); s_sScreenshotName = filename; - s_bScreenshot = true; + s_screenshot.Set(); } // Create On-Screen-Messages @@ -648,71 +643,122 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const bool Renderer::IsFrameDumping() { - if (s_bScreenshot) + if (s_screenshot.IsSet()) return true; #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_AVI_dumping = false; - OSD::AddMessage("Stop dumping frames"); - } - m_last_frame_dumped = false; #endif + + ShutdownFrameDumping(); return false; } +void Renderer::ShutdownFrameDumping() +{ + if (!m_frame_dump_thread_running.IsSet()) + return; + + FinishFrameData(); + m_frame_dump_thread_running.Clear(); + m_frame_dump_start.Set(); +} + void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, const AVIDump::Frame& state, bool swap_upside_down) { - if (w == 0 || h == 0) - return; + FinishFrameData(); - // TODO: Refactor this. Right now it's needed for the implace flipping of the image. - m_frame_data.assign(data, data + stride * h); - if (swap_upside_down) - FlipImageData(m_frame_data.data(), w, h, 4); + m_frame_dump_config = FrameDumpConfig{data, w, h, stride, swap_upside_down, state}; - // Save screenshot - if (s_bScreenshot) + if (!m_frame_dump_thread_running.IsSet()) { - std::lock_guard<std::mutex> lk(s_criticalScreenshot); + if (m_frame_dump_thread.joinable()) + m_frame_dump_thread.join(); + m_frame_dump_thread_running.Set(); + m_frame_dump_thread = std::thread(&Renderer::RunFrameDumps, this); + } - if (TextureToPng(m_frame_data.data(), stride, s_sScreenshotName, w, h, false)) - OSD::AddMessage("Screenshot saved to " + s_sScreenshotName); + m_frame_dump_start.Set(); + m_frame_dump_frame_running = true; +} - // Reset settings - s_sScreenshotName.clear(); - s_bScreenshot = false; - s_screenshotCompleted.Set(); - } +void Renderer::FinishFrameData() +{ + if (!m_frame_dump_frame_running) + return; -#if defined(HAVE_LIBAV) || defined(_WIN32) - if (SConfig::GetInstance().m_DumpFrames) + m_frame_dump_done.Wait(); + m_frame_dump_frame_running = false; +} + +void Renderer::RunFrameDumps() +{ + Common::SetCurrentThreadName("FrameDumping"); + bool avi_dump_started = false; + std::vector<u8> data; + + while (true) { - if (!m_last_frame_dumped) + m_frame_dump_start.Wait(); + if (!m_frame_dump_thread_running.IsSet()) + break; + + const auto config = m_frame_dump_config; + + // TODO: Refactor this. Right now it's needed for the implace flipping of the image. + data.assign(config.data, config.data + config.stride * config.height); + + // As we've done a copy now, there is no need to block the GPU thread any longer. + m_frame_dump_done.Set(); + + if (config.upside_down) + FlipImageData(data.data(), config.width, config.height, 4); + + // Save screenshot + if (s_screenshot.TestAndClear()) { - m_AVI_dumping = AVIDump::Start(w, h); + std::lock_guard<std::mutex> lk(s_criticalScreenshot); + + if (TextureToPng(data.data(), config.stride, s_sScreenshotName, config.width, config.height, + false)) + OSD::AddMessage("Screenshot saved to " + s_sScreenshotName); + + // Reset settings + s_sScreenshotName.clear(); + s_screenshotCompleted.Set(); } - if (m_AVI_dumping) + +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (SConfig::GetInstance().m_DumpFrames) { - AVIDump::AddFrame(m_frame_data.data(), w, h, stride, state); + if (!avi_dump_started) + { + if (AVIDump::Start(config.width, config.height)) + { + avi_dump_started = true; + } + else + { + SConfig::GetInstance().m_DumpFrames = false; + } + } + + AVIDump::AddFrame(data.data(), config.width, config.height, config.stride, config.state); } +#endif + } - m_last_frame_dumped = true; +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (avi_dump_started) + { + avi_dump_started = false; + AVIDump::Stop(); } #endif } -void Renderer::FinishFrameData() -{ -} - void Renderer::FlipImageData(u8* data, int w, int h, int pixel_width) { for (int y = 0; y < h / 2; ++y) |
