diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2020-10-21 09:37:16 -0500 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2020-10-22 12:17:26 -0500 |
| commit | 4807a5e15774b609da944f6d3a51fbe5c9957eb5 (patch) | |
| tree | 77d1514b4b702103a5d64b76c1336c9cb2f75473 /Source/Core/VideoCommon/RenderBase.cpp | |
| parent | 89b01cd6d352f8894eddccb36a13e8b873db5e61 (diff) | |
VideoCommon: FrameDump fixes/cleanups.
Diffstat (limited to 'Source/Core/VideoCommon/RenderBase.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/RenderBase.cpp | 91 |
1 files changed, 49 insertions, 42 deletions
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 4777314194..2f46beeb56 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -1409,17 +1409,13 @@ void Renderer::DumpCurrentFrame(const AbstractTexture* src_texture, copy_rect = src_texture->GetRect(); } - // Index 0 was just sent to FFMPEG dump. Swap with the second texture. - if (m_frame_dump_readback_textures[0]) - std::swap(m_frame_dump_readback_textures[0], m_frame_dump_readback_textures[1]); - if (!CheckFrameDumpReadbackTexture(target_width, target_height)) return; - m_frame_dump_readback_textures[0]->CopyFromTexture(src_texture, copy_rect, 0, 0, - m_frame_dump_readback_textures[0]->GetRect()); - m_last_frame_state = FrameDump::FetchState(ticks); - m_last_frame_exported = true; + m_frame_dump_readback_texture->CopyFromTexture(src_texture, copy_rect, 0, 0, + m_frame_dump_readback_texture->GetRect()); + m_last_frame_state = m_frame_dump.FetchState(ticks); + m_frame_dump_needs_flush = true; } bool Renderer::CheckFrameDumpRenderTexture(u32 target_width, u32 target_height) @@ -1450,7 +1446,7 @@ bool Renderer::CheckFrameDumpRenderTexture(u32 target_width, u32 target_height) bool Renderer::CheckFrameDumpReadbackTexture(u32 target_width, u32 target_height) { - std::unique_ptr<AbstractStagingTexture>& rbtex = m_frame_dump_readback_textures[0]; + std::unique_ptr<AbstractStagingTexture>& rbtex = m_frame_dump_readback_texture; if (rbtex && rbtex->GetWidth() == target_width && rbtex->GetHeight() == target_height) return true; @@ -1466,24 +1462,28 @@ bool Renderer::CheckFrameDumpReadbackTexture(u32 target_width, u32 target_height void Renderer::FlushFrameDump() { - if (!m_last_frame_exported) + if (!m_frame_dump_needs_flush) return; - // Ensure the previously-queued frame was encoded. + // Ensure dumping thread is done with output texture before swapping. FinishFrameData(); + std::swap(m_frame_dump_output_texture, m_frame_dump_readback_texture); + // Queue encoding of the last frame dumped. - std::unique_ptr<AbstractStagingTexture>& rbtex = m_frame_dump_readback_textures[0]; - rbtex->Flush(); - if (rbtex->Map()) + auto& output = m_frame_dump_output_texture; + output->Flush(); + if (output->Map()) + { + DumpFrameData(reinterpret_cast<u8*>(output->GetMappedPointer()), output->GetConfig().width, + output->GetConfig().height, static_cast<int>(output->GetMappedStride())); + } + else { - DumpFrameData(reinterpret_cast<u8*>(rbtex->GetMappedPointer()), rbtex->GetConfig().width, - rbtex->GetConfig().height, static_cast<int>(rbtex->GetMappedStride()), - m_last_frame_state); - rbtex->Unmap(); + ERROR_LOG(VIDEO, "Failed to map texture for dumping."); } - m_last_frame_exported = false; + m_frame_dump_needs_flush = false; // Shutdown frame dumping if it is no longer active. if (!IsFrameDumping()) @@ -1508,21 +1508,21 @@ void Renderer::ShutdownFrameDumping() m_frame_dump_thread.join(); m_frame_dump_render_framebuffer.reset(); m_frame_dump_render_texture.reset(); - for (auto& tex : m_frame_dump_readback_textures) - tex.reset(); + + m_frame_dump_readback_texture.reset(); + m_frame_dump_output_texture.reset(); } -void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, - const FrameDump::Frame& state) +void Renderer::DumpFrameData(const u8* data, int w, int h, int stride) { - m_frame_dump_config = FrameDumpConfig{data, w, h, stride, state}; + m_frame_dump_data = FrameDump::FrameData{data, w, h, stride, m_last_frame_state}; if (!m_frame_dump_thread_running.IsSet()) { 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); + m_frame_dump_thread = std::thread(&Renderer::FrameDumpThreadFunc, this); } // Wake worker thread up. @@ -1537,11 +1537,14 @@ void Renderer::FinishFrameData() m_frame_dump_done.Wait(); m_frame_dump_frame_running = false; + + m_frame_dump_output_texture->Unmap(); } -void Renderer::RunFrameDumps() +void Renderer::FrameDumpThreadFunc() { Common::SetCurrentThreadName("FrameDumping"); + bool dump_to_ffmpeg = !g_ActiveConfig.bDumpFramesAsImages; bool frame_dump_started = false; @@ -1561,14 +1564,14 @@ void Renderer::RunFrameDumps() if (!m_frame_dump_thread_running.IsSet()) break; - auto config = m_frame_dump_config; + auto frame = m_frame_dump_data; // Save screenshot if (m_screenshot_request.TestAndClear()) { std::lock_guard<std::mutex> lk(m_screenshot_lock); - if (TextureToPng(config.data, config.stride, m_screenshot_name, config.width, config.height, + if (TextureToPng(frame.data, frame.stride, m_screenshot_name, frame.width, frame.height, false)) OSD::AddMessage("Screenshot saved to " + m_screenshot_name); @@ -1582,9 +1585,9 @@ void Renderer::RunFrameDumps() if (!frame_dump_started) { if (dump_to_ffmpeg) - frame_dump_started = StartFrameDumpToFFMPEG(config); + frame_dump_started = StartFrameDumpToFFMPEG(frame); else - frame_dump_started = StartFrameDumpToImage(config); + frame_dump_started = StartFrameDumpToImage(frame); // Stop frame dumping if we fail to start. if (!frame_dump_started) @@ -1595,9 +1598,9 @@ void Renderer::RunFrameDumps() if (frame_dump_started) { if (dump_to_ffmpeg) - DumpFrameToFFMPEG(config); + DumpFrameToFFMPEG(frame); else - DumpFrameToImage(config); + DumpFrameToImage(frame); } } @@ -1614,29 +1617,29 @@ void Renderer::RunFrameDumps() #if defined(HAVE_FFMPEG) -bool Renderer::StartFrameDumpToFFMPEG(const FrameDumpConfig& config) +bool Renderer::StartFrameDumpToFFMPEG(const FrameDump::FrameData& frame) { - return FrameDump::Start(config.width, config.height); + return m_frame_dump.Start(frame.width, frame.height); } -void Renderer::DumpFrameToFFMPEG(const FrameDumpConfig& config) +void Renderer::DumpFrameToFFMPEG(const FrameDump::FrameData& frame) { - FrameDump::AddFrame(config.data, config.width, config.height, config.stride, config.state); + m_frame_dump.AddFrame(frame); } void Renderer::StopFrameDumpToFFMPEG() { - FrameDump::Stop(); + m_frame_dump.Stop(); } #else -bool Renderer::StartFrameDumpToFFMPEG(const FrameDumpConfig& config) +bool Renderer::StartFrameDumpToFFMPEG(const FrameDump::FrameData&) { return false; } -void Renderer::DumpFrameToFFMPEG(const FrameDumpConfig& config) +void Renderer::DumpFrameToFFMPEG(const FrameDump::FrameData&) { } @@ -1652,7 +1655,7 @@ std::string Renderer::GetFrameDumpNextImageFileName() const m_frame_dump_image_counter); } -bool Renderer::StartFrameDumpToImage(const FrameDumpConfig& config) +bool Renderer::StartFrameDumpToImage(const FrameDump::FrameData&) { m_frame_dump_image_counter = 1; if (!SConfig::GetInstance().m_DumpFramesSilent) @@ -1671,10 +1674,10 @@ bool Renderer::StartFrameDumpToImage(const FrameDumpConfig& config) return true; } -void Renderer::DumpFrameToImage(const FrameDumpConfig& config) +void Renderer::DumpFrameToImage(const FrameDump::FrameData& frame) { std::string filename = GetFrameDumpNextImageFileName(); - TextureToPng(config.data, config.stride, filename, config.width, config.height, false); + TextureToPng(frame.data, frame.stride, filename, frame.width, frame.height, false); m_frame_dump_image_counter++; } @@ -1718,6 +1721,10 @@ void Renderer::DoState(PointerWrap& p) // And actually display it. Swap(m_last_xfb_addr, m_last_xfb_width, m_last_xfb_stride, m_last_xfb_height, m_last_xfb_ticks); } + +#if defined(HAVE_FFMPEG) + m_frame_dump.DoState(p); +#endif } std::unique_ptr<VideoCommon::AsyncShaderCompiler> Renderer::CreateAsyncShaderCompiler() |
