summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMarkus Wick <degasus@users.noreply.github.com>2016-10-08 00:54:36 +0200
committerGitHub <noreply@github.com>2016-10-08 00:54:36 +0200
commita172bd7d8cac3c417e33ba8fafb89963fc8b5bbd (patch)
tree5b650dbbd073c0d43ca4eba4301705f31da28f85 /Source/Core
parent5e027a0817c4577539fc969c3cd7900553b3fb99 (diff)
parent8c999f9ee801116e723381432b96d8a9ae6ddc68 (diff)
Merge pull request #4318 from degasus/framedump
Renderer: Move framedumping logic to VideoCommon.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoBackends/D3D/Render.cpp56
-rw-r--r--Source/Core/VideoBackends/D3D12/Render.cpp62
-rw-r--r--Source/Core/VideoBackends/OGL/Render.cpp82
-rw-r--r--Source/Core/VideoBackends/Vulkan/Renderer.cpp82
-rw-r--r--Source/Core/VideoBackends/Vulkan/Renderer.h3
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp96
-rw-r--r--Source/Core/VideoCommon/RenderBase.h19
7 files changed, 146 insertions, 254 deletions
diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp
index 2997173014..fa0fe3581e 100644
--- a/Source/Core/VideoBackends/D3D/Render.cpp
+++ b/Source/Core/VideoBackends/D3D/Render.cpp
@@ -768,9 +768,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) ||
!fbWidth || !fbHeight)
{
- if (SConfig::GetInstance().m_DumpFrames && !frame_data.empty())
- AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight);
-
+ RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -780,9 +778,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
FramebufferManager::GetXFBSource(xfbAddr, fbStride, fbHeight, &xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
{
- if (SConfig::GetInstance().m_DumpFrames && !frame_data.empty())
- AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight);
-
+ RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -877,7 +873,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
}
// Dump frames
- if (SConfig::GetInstance().m_DumpFrames)
+ if (IsFrameDumping())
{
if (!s_screenshot_texture)
CreateScreenshotTexture();
@@ -888,47 +884,17 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
D3D::context->CopySubresourceRegion(s_screenshot_texture, 0, 0, 0, 0,
(ID3D11Resource*)D3D::GetBackBuffer()->GetTex(), 0,
&source_box);
- if (!bLastFrameDumped)
- {
- bAVIDumping = AVIDump::Start(source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR);
- if (!bAVIDumping)
- {
- PanicAlert("Error dumping frames to AVI.");
- }
- else
- {
- std::string msg = StringFromFormat("Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)",
- File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
- source_width, source_height);
- OSD::AddMessage(msg, 2000);
- }
- }
- if (bAVIDumping)
- {
- D3D11_MAPPED_SUBRESOURCE map;
- D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map);
+ D3D11_MAPPED_SUBRESOURCE map;
+ D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map);
- if (frame_data.capacity() != 3 * source_width * source_height)
- frame_data.resize(3 * source_width * source_height);
+ // TODO: This convertion is not needed. Get rid of it.
+ std::vector<u8> image(source_width * source_height * 3);
+ formatBufferDump((u8*)map.pData, image.data(), source_width, source_height, map.RowPitch);
- formatBufferDump((u8*)map.pData, &frame_data[0], source_width, source_height, map.RowPitch);
- FlipImageData(&frame_data[0], source_width, source_height);
- AVIDump::AddFrame(&frame_data[0], source_width, source_height);
- D3D::context->Unmap(s_screenshot_texture, 0);
- }
- bLastFrameDumped = true;
- }
- else
- {
- if (bLastFrameDumped && bAVIDumping)
- {
- AVIDump::Stop();
- std::vector<u8>().swap(frame_data);
- bAVIDumping = false;
- OSD::AddMessage("Stop dumping frames to AVI", 2000);
- }
- bLastFrameDumped = false;
+ DumpFrameData(image.data(), source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR, true);
+
+ D3D::context->Unmap(s_screenshot_texture, 0);
}
// Reset viewport for drawing text
diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp
index 9bbe2699ba..fb1740d9ac 100644
--- a/Source/Core/VideoBackends/D3D12/Render.cpp
+++ b/Source/Core/VideoBackends/D3D12/Render.cpp
@@ -711,9 +711,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) ||
!fb_width || !fb_height)
{
- if (SConfig::GetInstance().m_DumpFrames && !frame_data.empty())
- AVIDump::AddFrame(&frame_data[0], fb_width, fb_height);
-
+ RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -723,9 +721,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
FramebufferManager::GetXFBSource(xfb_addr, fb_stride, fb_height, &xfb_count);
if ((!xfb_source_list || xfb_count == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
{
- if (SConfig::GetInstance().m_DumpFrames && !frame_data.empty())
- AVIDump::AddFrame(&frame_data[0], fb_width, fb_height);
-
+ RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -832,7 +828,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
}
// Dump frames
- if (SConfig::GetInstance().m_DumpFrames)
+ if (IsFrameDumping())
{
if (!s_screenshot_texture)
CreateScreenshotTexture();
@@ -865,51 +861,19 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
D3D::command_list_mgr->ExecuteQueuedWork(true);
- if (!bLastFrameDumped)
- {
- bAVIDumping = AVIDump::Start(source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR);
- if (!bAVIDumping)
- {
- PanicAlert("Error dumping frames to AVI.");
- }
- else
- {
- std::string msg = StringFromFormat("Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)",
- File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
- source_width, source_height);
+ void* screenshot_texture_map;
+ D3D12_RANGE read_range = {0, dst_location.PlacedFootprint.Footprint.RowPitch * source_height};
+ CheckHR(s_screenshot_texture->Map(0, &read_range, &screenshot_texture_map));
- OSD::AddMessage(msg, 2000);
- }
- }
- if (bAVIDumping)
- {
- if (frame_data.capacity() != 3 * source_width * source_height)
- frame_data.resize(3 * source_width * source_height);
-
- void* screenshot_texture_map;
- D3D12_RANGE read_range = {0, dst_location.PlacedFootprint.Footprint.RowPitch * source_height};
- CheckHR(s_screenshot_texture->Map(0, &read_range, &screenshot_texture_map));
- formatBufferDump(static_cast<u8*>(screenshot_texture_map), &frame_data[0], source_width,
- source_height, dst_location.PlacedFootprint.Footprint.RowPitch);
+ // TODO: This convertion is not needed. Get rid of it.
+ std::vector<u8> image(source_width * source_height * 3);
+ formatBufferDump(static_cast<u8*>(screenshot_texture_map), image.data(), source_width,
+ source_height, dst_location.PlacedFootprint.Footprint.RowPitch);
- D3D12_RANGE write_range = {};
- s_screenshot_texture->Unmap(0, &write_range);
+ DumpFrameData(image.data(), source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR, true);
- FlipImageData(&frame_data[0], source_width, source_height);
- AVIDump::AddFrame(&frame_data[0], source_width, source_height);
- }
- bLastFrameDumped = true;
- }
- else
- {
- if (bLastFrameDumped && bAVIDumping)
- {
- AVIDump::Stop();
- std::vector<u8>().swap(frame_data);
- bAVIDumping = false;
- OSD::AddMessage("Stop dumping frames to AVI", 2000);
- }
- bLastFrameDumped = false;
+ D3D12_RANGE write_range = {};
+ s_screenshot_texture->Unmap(0, &write_range);
}
// Reset viewport for drawing text
diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp
index 21227a2614..2f53d0e9a6 100644
--- a/Source/Core/VideoBackends/OGL/Render.cpp
+++ b/Source/Core/VideoBackends/OGL/Render.cpp
@@ -32,9 +32,7 @@
#include "VideoBackends/OGL/TextureCache.h"
#include "VideoBackends/OGL/VertexManager.h"
-#if defined(HAVE_LIBAV) || defined(_WIN32)
#include "VideoCommon/AVIDump.h"
-#endif
#include "VideoCommon/BPFunctions.h"
#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/Fifo.h"
@@ -51,7 +49,6 @@ void VideoConfig::UpdateProjectionHack()
::UpdateProjectionHack(g_Config.iPhackvalue, g_Config.sPhackvalue);
}
-static int OSDInternalW, OSDInternalH;
static int s_max_texture_size = 0;
namespace OGL
@@ -333,9 +330,6 @@ static void InitDriverInfo()
// Init functions
Renderer::Renderer()
{
- OSDInternalW = 0;
- OSDInternalH = 0;
-
s_blendMode = 0;
bool bSuccess = true;
@@ -1344,16 +1338,6 @@ void Renderer::SetBlendMode(bool forceUpdate)
s_blendMode = newval;
}
-static void DumpFrame(const std::vector<u8>& data, int w, int h)
-{
-#if defined(HAVE_LIBAV) || defined(_WIN32)
- if (SConfig::GetInstance().m_DumpFrames && !data.empty())
- {
- AVIDump::AddFrame(&data[0], w, h);
- }
-#endif
-}
-
// This function has the final picture. We adjust the aspect ratio here.
void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
const EFBRectangle& rc, float Gamma)
@@ -1366,11 +1350,10 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
glDisable(GL_DEBUG_OUTPUT);
}
- static int w = 0, h = 0;
if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) ||
!fbWidth || !fbHeight)
{
- DumpFrame(frame_data, w, h);
+ RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -1380,7 +1363,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
FramebufferManager::GetXFBSource(xfbAddr, fbStride, fbHeight, &xfbCount);
if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0))
{
- DumpFrame(frame_data, w, h);
+ RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -1449,9 +1432,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
sourceRc.right -= Renderer::EFBToScaledX(fbStride - fbWidth);
}
- // Tell the OSD Menu about the current internal resolution
- OSDInternalW = xfbSource->sourceRc.GetWidth();
- OSDInternalH = xfbSource->sourceRc.GetHeight();
BlitScreen(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight);
}
@@ -1481,64 +1461,18 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
s_screenshotCompleted.Set();
}
-// Frame dumps are handled a little differently in Windows
-#if defined(HAVE_LIBAV) || defined(_WIN32)
- if (SConfig::GetInstance().m_DumpFrames)
+ if (IsFrameDumping())
{
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
-
- if (frame_data.empty() || w != flipped_trc.GetWidth() || h != flipped_trc.GetHeight())
- {
- w = flipped_trc.GetWidth();
- h = flipped_trc.GetHeight();
- frame_data.resize(4 * w * h);
- }
+ std::vector<u8> image(flipped_trc.GetWidth() * flipped_trc.GetHeight() * 4);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadPixels(flipped_trc.left, flipped_trc.bottom, w, h, GL_RGBA, GL_UNSIGNED_BYTE,
- &frame_data[0]);
- if (w > 0 && h > 0)
- {
- if (!bLastFrameDumped)
- {
- bAVIDumping = AVIDump::Start(w, h, AVIDump::DumpFormat::FORMAT_RGBA);
- if (!bAVIDumping)
- {
- 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 (bAVIDumping)
- {
- FlipImageData(&frame_data[0], w, h, 4);
- AVIDump::AddFrame(&frame_data[0], w, h);
- }
+ glReadPixels(flipped_trc.left, flipped_trc.bottom, flipped_trc.GetWidth(),
+ flipped_trc.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.data());
- bLastFrameDumped = true;
- }
- else
- {
- NOTICE_LOG(VIDEO, "Error reading framebuffer");
- }
+ DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(),
+ AVIDump::DumpFormat::FORMAT_RGBA, true);
}
- else
- {
- if (bLastFrameDumped && bAVIDumping)
- {
- AVIDump::Stop();
- std::vector<u8>().swap(frame_data);
- w = h = 0;
- bAVIDumping = false;
- OSD::AddMessage("Stop dumping frames", 2000);
- }
- bLastFrameDumped = false;
- }
-#endif
// Finish up the current frame, print some stats
SetWindowSize(fbStride, fbHeight);
diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp
index c8f9aaa4d3..42fd7373db 100644
--- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp
+++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp
@@ -26,10 +26,7 @@
#include "VideoBackends/Vulkan/Util.h"
#include "VideoBackends/Vulkan/VulkanContext.h"
-#if defined(HAVE_LIBAV) || defined(_WIN32)
#include "VideoCommon/AVIDump.h"
-#endif
-
#include "VideoCommon/BPFunctions.h"
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/ImageWrite.h"
@@ -65,15 +62,6 @@ Renderer::Renderer(std::unique_ptr<SwapChain> swap_chain) : m_swap_chain(std::mo
Renderer::~Renderer()
{
-#if defined(HAVE_LIBAV) || defined(_WIN32)
- // Stop frame dumping if it was left enabled at shutdown time.
- if (bAVIDumping)
- {
- AVIDump::Stop();
- bAVIDumping = false;
- }
-#endif
-
g_Config.bRunning = false;
UpdateActiveConfig();
DestroyScreenshotResources();
@@ -494,20 +482,22 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
// Draw to the screenshot buffer if needed.
- bool needs_screenshot = (s_bScreenshot || SConfig::GetInstance().m_DumpFrames);
+ bool needs_framedump = IsFrameDumping();
+ bool needs_screenshot = s_bScreenshot || needs_framedump;
if (needs_screenshot && DrawScreenshot(source_rc, efb_color_texture))
{
if (s_bScreenshot)
+ {
WriteScreenshot();
+ }
- if (SConfig::GetInstance().m_DumpFrames)
- WriteFrameDump();
- }
- else
- {
- // Stop frame dump if requested.
- if (bAVIDumping)
- StopFrameDump();
+ if (needs_framedump)
+ {
+ DumpFrameData(reinterpret_cast<const u8*>(m_screenshot_readback_texture->GetMapPointer()),
+ static_cast<int>(m_screenshot_render_texture->GetWidth()),
+ static_cast<int>(m_screenshot_render_texture->GetHeight()),
+ AVIDump::DumpFormat::FORMAT_RGBA);
+ }
}
// Restore the EFB color texture to color attachment ready for rendering the next frame.
@@ -785,56 +775,6 @@ void Renderer::WriteScreenshot()
s_screenshotCompleted.Set();
}
-void Renderer::WriteFrameDump()
-{
-#if defined(HAVE_LIBAV) || defined(_WIN32)
- if (!bLastFrameDumped)
- {
- bLastFrameDumped = true;
- bAVIDumping = AVIDump::Start(static_cast<int>(m_screenshot_render_texture->GetWidth()),
- static_cast<int>(m_screenshot_render_texture->GetHeight()),
- AVIDump::DumpFormat::FORMAT_RGBA);
-
- if (!bAVIDumping)
- {
- OSD::AddMessage("Failed to start frame dumping.", 2000);
- return;
- }
-
- OSD::AddMessage(StringFromFormat("Frame dumping started (%ux%u RGBA8).",
- m_screenshot_render_texture->GetWidth(),
- m_screenshot_render_texture->GetHeight()),
- 2000);
- }
-
- if (bAVIDumping)
- {
- AVIDump::AddFrame(reinterpret_cast<const u8*>(m_screenshot_readback_texture->GetMapPointer()),
- static_cast<int>(m_screenshot_render_texture->GetWidth()),
- static_cast<int>(m_screenshot_render_texture->GetHeight()));
- }
-#else
- if (!bLastFrameDumped)
- {
- OSD::AddMessage("Dumping frames not supported", 2000);
- bLastFrameDumped = true;
- }
-#endif
-}
-
-void Renderer::StopFrameDump()
-{
-#if defined(HAVE_LIBAV) || defined(_WIN32)
- if (bAVIDumping)
- {
- OSD::AddMessage("Frame dumping stopped.", 2000);
- bAVIDumping = false;
- bLastFrameDumped = false;
- AVIDump::Stop();
- }
-#endif
-}
-
void Renderer::CheckForTargetResize(u32 fb_width, u32 fb_stride, u32 fb_height)
{
if (FramebufferManagerBase::LastXfbWidth() == fb_stride &&
diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.h b/Source/Core/VideoBackends/Vulkan/Renderer.h
index f292d722a0..b80b6c191b 100644
--- a/Source/Core/VideoBackends/Vulkan/Renderer.h
+++ b/Source/Core/VideoBackends/Vulkan/Renderer.h
@@ -100,9 +100,6 @@ private:
bool ResizeScreenshotBuffer(u32 new_width, u32 new_height);
void DestroyScreenshotResources();
void WriteScreenshot();
- void WriteFrameDump();
- void StopFrameDump();
-
FramebufferManager* m_framebuffer_mgr = nullptr;
VkSemaphore m_image_available_semaphore = VK_NULL_HANDLE;
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;