mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-12 22:56:52 +01:00
Merge some frame dumping code to VideoCommon, fixes a memory leak in D3D9 and OpenGL if emulation is stopped while dumping frames.
Breaks D3D11 frame dumping for some weird reason (memory corruption or whatever?).
This commit is contained in:
parent
bd4a5b5ef6
commit
c710ea33f9
@ -42,6 +42,7 @@
|
|||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
#include "XFMemory.h"
|
#include "XFMemory.h"
|
||||||
#include "FifoPlayer/FifoRecorder.h"
|
#include "FifoPlayer/FifoRecorder.h"
|
||||||
|
#include "AVIDump.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -52,7 +53,6 @@ int OSDChoice, OSDTime;
|
|||||||
|
|
||||||
Renderer *g_renderer = NULL;
|
Renderer *g_renderer = NULL;
|
||||||
|
|
||||||
bool bLastFrameDumped = false;
|
|
||||||
std::mutex Renderer::s_criticalScreenshot;
|
std::mutex Renderer::s_criticalScreenshot;
|
||||||
std::string Renderer::s_sScreenshotName;
|
std::string Renderer::s_sScreenshotName;
|
||||||
|
|
||||||
@ -81,15 +81,28 @@ bool Renderer::s_EnableDLCachingAfterRecording;
|
|||||||
|
|
||||||
unsigned int Renderer::prev_efb_format = (unsigned int)-1;
|
unsigned int Renderer::prev_efb_format = (unsigned int)-1;
|
||||||
|
|
||||||
Renderer::Renderer()
|
Renderer::Renderer() : frame_data(NULL), bLastFrameDumped(false)
|
||||||
{
|
{
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
|
|
||||||
|
#if defined _WIN32 || defined HAVE_LIBAV
|
||||||
|
bAVIDumping = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::~Renderer()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
// invalidate previous efb format
|
// invalidate previous efb format
|
||||||
prev_efb_format = (unsigned int)-1;
|
prev_efb_format = (unsigned int)-1;
|
||||||
|
|
||||||
|
#if defined _WIN32 || defined HAVE_LIBAV
|
||||||
|
if (g_ActiveConfig.bDumpFrames && bLastFrameDumped && bAVIDumping)
|
||||||
|
AVIDump::Stop();
|
||||||
|
#else
|
||||||
|
if (f_pFrameDump.IsOpen())
|
||||||
|
f_pFrameDump.Close();
|
||||||
|
#endif
|
||||||
|
delete[] frame_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma)
|
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma)
|
||||||
|
@ -132,9 +132,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static std::mutex s_criticalScreenshot;
|
|
||||||
static std::string s_sScreenshotName;
|
|
||||||
|
|
||||||
static void CalculateTargetScale(int x, int y, int &scaledX, int &scaledY);
|
static void CalculateTargetScale(int x, int y, int &scaledX, int &scaledY);
|
||||||
static bool CalculateTargetSize(int multiplier = 1);
|
static bool CalculateTargetSize(int multiplier = 1);
|
||||||
static void CalculateXYScale(const TargetRectangle& dst_rect);
|
static void CalculateXYScale(const TargetRectangle& dst_rect);
|
||||||
@ -143,6 +140,16 @@ protected:
|
|||||||
static void RecordVideoMemory();
|
static void RecordVideoMemory();
|
||||||
|
|
||||||
static volatile bool s_bScreenshot;
|
static volatile bool s_bScreenshot;
|
||||||
|
static std::mutex s_criticalScreenshot;
|
||||||
|
static std::string s_sScreenshotName;
|
||||||
|
|
||||||
|
#if defined _WIN32 || defined HAVE_LIBAV
|
||||||
|
bool bAVIDumping;
|
||||||
|
#else
|
||||||
|
File::IOFile pFrameDump;
|
||||||
|
#endif
|
||||||
|
char* frame_data;
|
||||||
|
bool bLastFrameDumped;
|
||||||
|
|
||||||
// The framebuffer size
|
// The framebuffer size
|
||||||
static int s_target_width;
|
static int s_target_width;
|
||||||
|
@ -64,8 +64,6 @@ ID3D11DepthStencilState* resetdepthstate = NULL;
|
|||||||
ID3D11RasterizerState* resetraststate = NULL;
|
ID3D11RasterizerState* resetraststate = NULL;
|
||||||
|
|
||||||
static ID3D11Texture2D* s_screenshot_texture = NULL;
|
static ID3D11Texture2D* s_screenshot_texture = NULL;
|
||||||
static bool s_bAVIDumping;
|
|
||||||
static char *s_frame_data = NULL;
|
|
||||||
|
|
||||||
// GX pipeline state
|
// GX pipeline state
|
||||||
struct
|
struct
|
||||||
@ -355,9 +353,6 @@ Renderer::Renderer()
|
|||||||
|
|
||||||
SetupDeviceObjects();
|
SetupDeviceObjects();
|
||||||
|
|
||||||
bLastFrameDumped = false;
|
|
||||||
s_bAVIDumping = false;
|
|
||||||
|
|
||||||
|
|
||||||
// Setup GX pipeline state
|
// Setup GX pipeline state
|
||||||
memset(&gx_state.blenddc, 0, sizeof(gx_state.blenddc));
|
memset(&gx_state.blenddc, 0, sizeof(gx_state.blenddc));
|
||||||
@ -406,15 +401,6 @@ Renderer::Renderer()
|
|||||||
|
|
||||||
Renderer::~Renderer()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && bLastFrameDumped && s_bAVIDumping)
|
|
||||||
{
|
|
||||||
SAFE_DELETE_ARRAY(s_frame_data);
|
|
||||||
|
|
||||||
AVIDump::Stop();
|
|
||||||
s_bAVIDumping = false;
|
|
||||||
bLastFrameDumped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TeardownDeviceObjects();
|
TeardownDeviceObjects();
|
||||||
D3D::EndFrame();
|
D3D::EndFrame();
|
||||||
D3D::Present();
|
D3D::Present();
|
||||||
@ -900,8 +886,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
{
|
{
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
AVIDump::AddFrame(s_frame_data);
|
AVIDump::AddFrame(frame_data);
|
||||||
|
|
||||||
Core::Callback_VideoCopiedToXFB(false);
|
Core::Callback_VideoCopiedToXFB(false);
|
||||||
return;
|
return;
|
||||||
@ -914,8 +900,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
AVIDump::AddFrame(s_frame_data);
|
AVIDump::AddFrame(frame_data);
|
||||||
|
|
||||||
Core::Callback_VideoCopiedToXFB(false);
|
Core::Callback_VideoCopiedToXFB(false);
|
||||||
return;
|
return;
|
||||||
@ -1034,8 +1020,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
{
|
{
|
||||||
s_recordWidth = dst_rect.GetWidth();
|
s_recordWidth = dst_rect.GetWidth();
|
||||||
s_recordHeight = dst_rect.GetHeight();
|
s_recordHeight = dst_rect.GetHeight();
|
||||||
s_bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
||||||
if (!s_bAVIDumping)
|
if (!bAVIDumping)
|
||||||
{
|
{
|
||||||
PanicAlert("Error dumping frames to AVI.");
|
PanicAlert("Error dumping frames to AVI.");
|
||||||
}
|
}
|
||||||
@ -1047,33 +1033,33 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
OSD::AddMessage(msg, 2000);
|
OSD::AddMessage(msg, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s_bAVIDumping)
|
if (bAVIDumping)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map);
|
D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map);
|
||||||
|
|
||||||
if (!s_frame_data || w != s_recordWidth || h != s_recordHeight)
|
if (!frame_data || w != s_recordWidth || h != s_recordHeight)
|
||||||
{
|
{
|
||||||
delete[] s_frame_data;
|
delete[] frame_data;
|
||||||
s_frame_data = new char[3 * s_recordWidth * s_recordHeight];
|
frame_data = new char[3 * s_recordWidth * s_recordHeight];
|
||||||
w = s_recordWidth;
|
w = s_recordWidth;
|
||||||
h = s_recordHeight;
|
h = s_recordHeight;
|
||||||
}
|
}
|
||||||
formatBufferDump((char*)map.pData, s_frame_data, s_recordWidth, s_recordHeight, map.RowPitch);
|
formatBufferDump((char*)map.pData, frame_data, s_recordWidth, s_recordHeight, map.RowPitch);
|
||||||
AVIDump::AddFrame(s_frame_data);
|
AVIDump::AddFrame(frame_data);
|
||||||
D3D::context->Unmap(s_screenshot_texture, 0);
|
D3D::context->Unmap(s_screenshot_texture, 0);
|
||||||
}
|
}
|
||||||
bLastFrameDumped = true;
|
bLastFrameDumped = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bLastFrameDumped && s_bAVIDumping)
|
if (bLastFrameDumped && bAVIDumping)
|
||||||
{
|
{
|
||||||
SAFE_DELETE_ARRAY(s_frame_data);
|
SAFE_DELETE_ARRAY(frame_data);
|
||||||
w = h = 0;
|
w = h = 0;
|
||||||
|
|
||||||
AVIDump::Stop();
|
AVIDump::Stop();
|
||||||
s_bAVIDumping = false;
|
bAVIDumping = false;
|
||||||
OSD::AddMessage("Stop dumping frames to AVI", 2000);
|
OSD::AddMessage("Stop dumping frames to AVI", 2000);
|
||||||
}
|
}
|
||||||
bLastFrameDumped = false;
|
bLastFrameDumped = false;
|
||||||
|
@ -67,7 +67,6 @@ static bool IS_AMD;
|
|||||||
static char *st;
|
static char *st;
|
||||||
|
|
||||||
static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL;
|
static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL;
|
||||||
static bool s_bAVIDumping;
|
|
||||||
|
|
||||||
|
|
||||||
// State translation lookup tables
|
// State translation lookup tables
|
||||||
@ -292,9 +291,6 @@ Renderer::Renderer()
|
|||||||
// Make sure to use valid texture sizes
|
// Make sure to use valid texture sizes
|
||||||
D3D::FixTextureSize(s_target_width, s_target_height);
|
D3D::FixTextureSize(s_target_width, s_target_height);
|
||||||
|
|
||||||
bLastFrameDumped = false;
|
|
||||||
s_bAVIDumping = false;
|
|
||||||
|
|
||||||
// We're not using fixed function.
|
// We're not using fixed function.
|
||||||
// Let's just set the matrices to identity to be sure.
|
// Let's just set the matrices to identity to be sure.
|
||||||
D3DXMATRIX mtx;
|
D3DXMATRIX mtx;
|
||||||
@ -337,10 +333,6 @@ Renderer::~Renderer()
|
|||||||
D3D::Present();
|
D3D::Present();
|
||||||
D3D::Close();
|
D3D::Close();
|
||||||
|
|
||||||
if (s_bAVIDumping)
|
|
||||||
{
|
|
||||||
AVIDump::Stop();
|
|
||||||
}
|
|
||||||
delete[] st;
|
delete[] st;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,11 +831,10 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
|
|||||||
// This function has the final picture. We adjust the aspect ratio here.
|
// This function has the final picture. We adjust the aspect ratio here.
|
||||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
||||||
{
|
{
|
||||||
static char* data = 0;
|
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && data)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
AVIDump::AddFrame(data);
|
AVIDump::AddFrame(frame_data);
|
||||||
|
|
||||||
Core::Callback_VideoCopiedToXFB(false);
|
Core::Callback_VideoCopiedToXFB(false);
|
||||||
return;
|
return;
|
||||||
@ -857,8 +848,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && data)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
AVIDump::AddFrame(data);
|
AVIDump::AddFrame(frame_data);
|
||||||
|
|
||||||
Core::Callback_VideoCopiedToXFB(false);
|
Core::Callback_VideoCopiedToXFB(false);
|
||||||
return;
|
return;
|
||||||
@ -1038,8 +1029,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
{
|
{
|
||||||
s_recordWidth = dst_rect.GetWidth();
|
s_recordWidth = dst_rect.GetWidth();
|
||||||
s_recordHeight = dst_rect.GetHeight();
|
s_recordHeight = dst_rect.GetHeight();
|
||||||
s_bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
|
||||||
if (!s_bAVIDumping)
|
if (!bAVIDumping)
|
||||||
{
|
{
|
||||||
PanicAlert("Error dumping frames to AVI.");
|
PanicAlert("Error dumping frames to AVI.");
|
||||||
}
|
}
|
||||||
@ -1051,20 +1042,20 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
OSD::AddMessage(msg, 2000);
|
OSD::AddMessage(msg, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s_bAVIDumping)
|
if (bAVIDumping)
|
||||||
{
|
{
|
||||||
D3DLOCKED_RECT rect;
|
D3DLOCKED_RECT rect;
|
||||||
if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, dst_rect.AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
|
if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, dst_rect.AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
|
||||||
{
|
{
|
||||||
if (!data || w != s_recordWidth || h != s_recordHeight)
|
if (!frame_data || w != s_recordWidth || h != s_recordHeight)
|
||||||
{
|
{
|
||||||
free(data);
|
delete[] frame_data;
|
||||||
data = (char*)malloc(3 * s_recordWidth * s_recordHeight);
|
frame_data = new char[3 * s_recordWidth * s_recordHeight];
|
||||||
w = s_recordWidth;
|
w = s_recordWidth;
|
||||||
h = s_recordHeight;
|
h = s_recordHeight;
|
||||||
}
|
}
|
||||||
formatBufferDump((const char*)rect.pBits, data, s_recordWidth, s_recordHeight, rect.Pitch);
|
formatBufferDump((const char*)rect.pBits, frame_data, s_recordWidth, s_recordHeight, rect.Pitch);
|
||||||
AVIDump::AddFrame(data);
|
AVIDump::AddFrame(frame_data);
|
||||||
ScreenShootMEMSurface->UnlockRect();
|
ScreenShootMEMSurface->UnlockRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1072,16 +1063,16 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bLastFrameDumped && s_bAVIDumping)
|
if (bLastFrameDumped && bAVIDumping)
|
||||||
{
|
{
|
||||||
if (data)
|
if (frame_data)
|
||||||
{
|
{
|
||||||
free(data);
|
delete[] frame_data;
|
||||||
data = 0;
|
frame_data = 0;
|
||||||
w = h = 0;
|
w = h = 0;
|
||||||
}
|
}
|
||||||
AVIDump::Stop();
|
AVIDump::Stop();
|
||||||
s_bAVIDumping = false;
|
bAVIDumping = false;
|
||||||
OSD::AddMessage("Stop dumping frames to AVI", 2000);
|
OSD::AddMessage("Stop dumping frames to AVI", 2000);
|
||||||
}
|
}
|
||||||
bLastFrameDumped = false;
|
bLastFrameDumped = false;
|
||||||
|
@ -110,12 +110,6 @@ int s_fps=0;
|
|||||||
|
|
||||||
RasterFont* s_pfont = NULL;
|
RasterFont* s_pfont = NULL;
|
||||||
|
|
||||||
#if defined _WIN32 || defined HAVE_LIBAV
|
|
||||||
static bool s_bAVIDumping = false;
|
|
||||||
#else
|
|
||||||
static File::IOFile f_pFrameDump;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
|
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
|
||||||
static int s_MSAASamples = 1;
|
static int s_MSAASamples = 1;
|
||||||
static int s_MSAACoverageSamples = 0;
|
static int s_MSAACoverageSamples = 0;
|
||||||
@ -250,9 +244,6 @@ Renderer::Renderer()
|
|||||||
|
|
||||||
s_fps=0;
|
s_fps=0;
|
||||||
s_blendMode = 0;
|
s_blendMode = 0;
|
||||||
#if defined _WIN32 || defined HAVE_LIBAV
|
|
||||||
s_bAVIDumping = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined HAVE_CG && HAVE_CG
|
#if defined HAVE_CG && HAVE_CG
|
||||||
g_cgcontext = cgCreateContext();
|
g_cgcontext = cgCreateContext();
|
||||||
@ -516,19 +507,6 @@ Renderer::~Renderer()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
delete g_framebuffer_manager;
|
delete g_framebuffer_manager;
|
||||||
|
|
||||||
#if defined _WIN32 || defined HAVE_LIBAV
|
|
||||||
if(s_bAVIDumping)
|
|
||||||
{
|
|
||||||
AVIDump::Stop();
|
|
||||||
bLastFrameDumped = false;
|
|
||||||
s_bAVIDumping = false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (f_pFrameDump.IsOpen())
|
|
||||||
f_pFrameDump.Close();
|
|
||||||
s_bLastFrameDumped = false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create On-Screen-Messages
|
// Create On-Screen-Messages
|
||||||
@ -947,15 +925,14 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
|||||||
// This function has the final picture. We adjust the aspect ratio here.
|
// This function has the final picture. We adjust the aspect ratio here.
|
||||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
|
||||||
{
|
{
|
||||||
static u8 *data = NULL;
|
|
||||||
static int w = 0, h = 0;
|
static int w = 0, h = 0;
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && data)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
AVIDump::AddFrame((char *) data);
|
AVIDump::AddFrame(frame_data);
|
||||||
#elif defined HAVE_LIBAV
|
#elif defined HAVE_LIBAV
|
||||||
AVIDump::AddFrame(data, w, h);
|
AVIDump::AddFrame(frame_data, w, h);
|
||||||
#endif
|
#endif
|
||||||
Core::Callback_VideoCopiedToXFB(false);
|
Core::Callback_VideoCopiedToXFB(false);
|
||||||
return;
|
return;
|
||||||
@ -969,12 +946,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bDumpFrames && data)
|
if (g_ActiveConfig.bDumpFrames && frame_data)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
AVIDump::AddFrame((char *) data);
|
AVIDump::AddFrame(frame_data);
|
||||||
#elif defined HAVE_LIBAV
|
#elif defined HAVE_LIBAV
|
||||||
AVIDump::AddFrame(data, w, h);
|
AVIDump::AddFrame(frame_data, w, h);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
Core::Callback_VideoCopiedToXFB(false);
|
Core::Callback_VideoCopiedToXFB(false);
|
||||||
@ -1135,26 +1112,26 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
if (g_ActiveConfig.bDumpFrames)
|
if (g_ActiveConfig.bDumpFrames)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||||
if (!data || w != dst_rect.GetWidth() ||
|
if (!frame_data || w != dst_rect.GetWidth() ||
|
||||||
h != dst_rect.GetHeight())
|
h != dst_rect.GetHeight())
|
||||||
{
|
{
|
||||||
if (data) delete[] data;
|
if (frame_data) delete[] frame_data;
|
||||||
w = dst_rect.GetWidth();
|
w = dst_rect.GetWidth();
|
||||||
h = dst_rect.GetHeight();
|
h = dst_rect.GetHeight();
|
||||||
data = new u8[3 * w * h];
|
frame_data = new char[3 * w * h];
|
||||||
}
|
}
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data);
|
||||||
if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0)
|
if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0)
|
||||||
{
|
{
|
||||||
if (!bLastFrameDumped)
|
if (!bLastFrameDumped)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
s_bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), w, h);
|
bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), w, h);
|
||||||
#else
|
#else
|
||||||
s_bAVIDumping = AVIDump::Start(w, h);
|
bAVIDumping = AVIDump::Start(w, h);
|
||||||
#endif
|
#endif
|
||||||
if (!s_bAVIDumping)
|
if (!bAVIDumping)
|
||||||
OSD::AddMessage("AVIDump Start failed", 2000);
|
OSD::AddMessage("AVIDump Start failed", 2000);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1163,13 +1140,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), w, h).c_str(), 2000);
|
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), w, h).c_str(), 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s_bAVIDumping)
|
if (bAVIDumping)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
AVIDump::AddFrame((char *) data);
|
AVIDump::AddFrame(frame_data);
|
||||||
#else
|
#else
|
||||||
FlipImageData(data, w, h);
|
FlipImageData(frame_data, w, h);
|
||||||
AVIDump::AddFrame(data, w, h);
|
AVIDump::AddFrame(frame_data, w, h);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1180,16 +1157,16 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bLastFrameDumped && s_bAVIDumping)
|
if (bLastFrameDumped && bAVIDumping)
|
||||||
{
|
{
|
||||||
if (data)
|
if (frame_data)
|
||||||
{
|
{
|
||||||
delete[] data;
|
delete[] frame_data;
|
||||||
data = NULL;
|
frame_data = NULL;
|
||||||
w = h = 0;
|
w = h = 0;
|
||||||
}
|
}
|
||||||
AVIDump::Stop();
|
AVIDump::Stop();
|
||||||
s_bAVIDumping = false;
|
bAVIDumping = false;
|
||||||
OSD::AddMessage("Stop dumping frames", 2000);
|
OSD::AddMessage("Stop dumping frames", 2000);
|
||||||
}
|
}
|
||||||
bLastFrameDumped = false;
|
bLastFrameDumped = false;
|
||||||
@ -1201,16 +1178,16 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
std::string movie_file_name;
|
std::string movie_file_name;
|
||||||
w = dst_rect.GetWidth();
|
w = dst_rect.GetWidth();
|
||||||
h = dst_rect.GetHeight();
|
h = dst_rect.GetHeight();
|
||||||
data = new u8[3 * w * h];
|
frame_data = new u8[3 * w * h];
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data);
|
||||||
if (GL_REPORT_ERROR() == GL_NO_ERROR)
|
if (GL_REPORT_ERROR() == GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
if (!s_bLastFrameDumped)
|
if (!bLastFrameDumped)
|
||||||
{
|
{
|
||||||
movie_file_name = File::GetUserPath(D_DUMPFRAMES_IDX) + "framedump.raw";
|
movie_file_name = File::GetUserPath(D_DUMPFRAMES_IDX) + "framedump.raw";
|
||||||
f_pFrameDump.Open(movie_file_name, "wb");
|
pFrameDump.Open(movie_file_name, "wb");
|
||||||
if (!f_pFrameDump)
|
if (!pFrameDump)
|
||||||
OSD::AddMessage("Error opening framedump.raw for writing.", 2000);
|
OSD::AddMessage("Error opening framedump.raw for writing.", 2000);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1219,22 +1196,22 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
OSD::AddMessage(msg, 2000);
|
OSD::AddMessage(msg, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (f_pFrameDump)
|
if (pFrameDump)
|
||||||
{
|
{
|
||||||
FlipImageData(data, w, h);
|
FlipImageData(frame_data, w, h);
|
||||||
f_pFrameDump.WriteBytes(data, w * 3 * h);
|
pFrameDump.WriteBytes(frame_data, w * 3 * h);
|
||||||
f_pFrameDump.Flush();
|
pFrameDump.Flush();
|
||||||
}
|
}
|
||||||
s_bLastFrameDumped = true;
|
bLastFrameDumped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] data;
|
delete[] frame_data;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (s_bLastFrameDumped)
|
if (bLastFrameDumped)
|
||||||
f_pFrameDump.Close();
|
pFrameDump.Close();
|
||||||
s_bLastFrameDumped = false;
|
bLastFrameDumped = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user