Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Framedump: General code cleanup. #4320

Merged
merged 4 commits into from
Oct 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 3 additions & 23 deletions Source/Core/VideoBackends/D3D/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,30 +745,13 @@ bool Renderer::SaveScreenshot(const std::string& filename, const TargetRectangle
return saved_png;
}

void formatBufferDump(const u8* in, u8* out, int w, int h, int p)
{
for (int y = 0; y < h; ++y)
{
auto line = (in + (h - y - 1) * p);
for (int x = 0; x < w; ++x)
{
out[0] = line[2];
out[1] = line[1];
out[2] = line[0];
out += 3;
line += 4;
}
}
}

// 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)
{
if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) ||
!fbWidth || !fbHeight)
{
RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
Expand All @@ -778,7 +761,6 @@ 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)
{
RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
Expand Down Expand Up @@ -888,11 +870,9 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
D3D11_MAPPED_SUBRESOURCE map;
D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map);

// 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);

DumpFrameData(image.data(), source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR, true);
DumpFrameData(reinterpret_cast<const u8*>(map.pData), source_width, source_height, map.RowPitch,
AVIDump::DumpFormat::FORMAT_RGBA);
FinishFrameData();

D3D::context->Unmap(s_screenshot_texture, 0);
}
Expand Down
28 changes: 4 additions & 24 deletions Source/Core/VideoBackends/D3D12/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,30 +688,13 @@ bool Renderer::SaveScreenshot(const std::string& filename, const TargetRectangle
return saved_png;
}

void formatBufferDump(const u8* in, u8* out, int w, int h, int p)
{
for (int y = 0; y < h; ++y)
{
auto line = (in + (h - y - 1) * p);
for (int x = 0; x < w; ++x)
{
out[0] = line[2];
out[1] = line[1];
out[2] = line[0];
out += 3;
line += 4;
}
}
}

// This function has the final picture. We adjust the aspect ratio here.
void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height,
const EFBRectangle& rc, float gamma)
{
if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) ||
!fb_width || !fb_height)
{
RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
Expand All @@ -721,7 +704,6 @@ 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)
{
RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
Expand Down Expand Up @@ -865,12 +847,10 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
D3D12_RANGE read_range = {0, dst_location.PlacedFootprint.Footprint.RowPitch * source_height};
CheckHR(s_screenshot_texture->Map(0, &read_range, &screenshot_texture_map));

// 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);

DumpFrameData(image.data(), source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR, true);
DumpFrameData(reinterpret_cast<const u8*>(screenshot_texture_map), source_width, source_height,
dst_location.PlacedFootprint.Footprint.RowPitch,
AVIDump::DumpFormat::FORMAT_RGBA);
FinishFrameData();

D3D12_RANGE write_range = {};
s_screenshot_texture->Unmap(0, &write_range);
Expand Down
5 changes: 2 additions & 3 deletions Source/Core/VideoBackends/OGL/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) ||
!fbWidth || !fbHeight)
{
RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
Expand All @@ -1363,7 +1362,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
FramebufferManager::GetXFBSource(xfbAddr, fbStride, fbHeight, &xfbCount);
if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0))
{
RepeatFrameDumpFrame();
Core::Callback_VideoCopiedToXFB(false);
return;
}
Expand Down Expand Up @@ -1471,7 +1469,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
flipped_trc.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.data());

DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(),
AVIDump::DumpFormat::FORMAT_RGBA, true);
flipped_trc.GetWidth() * 4, AVIDump::DumpFormat::FORMAT_RGBA, true);
FinishFrameData();
}
// Finish up the current frame, print some stats

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/VideoBackends/Vulkan/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,9 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
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()),
static_cast<int>(m_screenshot_readback_texture->GetRowStride()),
AVIDump::DumpFormat::FORMAT_RGBA);
FinishFrameData();
}
}

Expand Down
15 changes: 7 additions & 8 deletions Source/Core/VideoCommon/AVIDump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ static AVStream* s_stream = nullptr;
static AVFrame* s_src_frame = nullptr;
static AVFrame* s_scaled_frame = nullptr;
static AVPixelFormat s_pix_fmt = AV_PIX_FMT_BGR24;
static int s_bytes_per_pixel;
static SwsContext* s_sws_context = nullptr;
static int s_width;
static int s_height;
Expand All @@ -52,6 +51,7 @@ static AVIDump::DumpFormat s_current_format;
static const u8* s_stored_frame_data;
static int s_stored_frame_width;
static int s_stored_frame_height;
static int s_stored_frame_stride;

static void InitAVCodec()
{
Expand All @@ -68,12 +68,10 @@ bool AVIDump::Start(int w, int h, DumpFormat format)
if (format == DumpFormat::FORMAT_BGR)
{
s_pix_fmt = AV_PIX_FMT_BGR24;
s_bytes_per_pixel = 3;
}
else
{
s_pix_fmt = AV_PIX_FMT_RGBA;
s_bytes_per_pixel = 4;
}

s_current_format = format;
Expand Down Expand Up @@ -181,18 +179,18 @@ static void PreparePacket(AVPacket* pkt)
pkt->size = 0;
}

void AVIDump::AddFrame(const u8* data, int width, int height)
void AVIDump::AddFrame(const u8* data, int width, int height, int stride)
{
// Store current frame data in case frame dumping stops before next frame update,
// but make sure that you don't store the last stored frame and check the resolution upon
// closing the file or else you store recursion, and dolphins don't like recursion.
if (!s_stop_dumping)
{
StoreFrameData(data, width, height);
StoreFrameData(data, width, height, stride);
CheckResolution(width, height);
}
s_src_frame->data[0] = const_cast<u8*>(data);
s_src_frame->linesize[0] = width * s_bytes_per_pixel;
s_src_frame->linesize[0] = stride;
s_src_frame->format = s_pix_fmt;
s_src_frame->width = s_width;
s_src_frame->height = s_height;
Expand Down Expand Up @@ -267,7 +265,7 @@ void AVIDump::Stop()
{
s_stop_dumping = true;
// Write the last stored frame just in case frame dumping stops before the next frame update
AddFrame(s_stored_frame_data, s_stored_frame_width, s_stored_frame_height);
AddFrame(s_stored_frame_data, s_stored_frame_width, s_stored_frame_height, s_stored_frame_stride);
av_write_trailer(s_format_context);
CloseFile();
s_file_index = 0;
Expand Down Expand Up @@ -328,9 +326,10 @@ void AVIDump::CheckResolution(int width, int height)
}
}

void AVIDump::StoreFrameData(const u8* data, int width, int height)
void AVIDump::StoreFrameData(const u8* data, int width, int height, int stride)
{
s_stored_frame_data = data;
s_stored_frame_width = width;
s_stored_frame_height = height;
s_stored_frame_stride = stride;
}
4 changes: 2 additions & 2 deletions Source/Core/VideoCommon/AVIDump.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class AVIDump
static bool CreateFile();
static void CloseFile();
static void CheckResolution(int width, int height);
static void StoreFrameData(const u8* data, int width, int height);
static void StoreFrameData(const u8* data, int width, int height, int stride);

public:
enum class DumpFormat
Expand All @@ -22,7 +22,7 @@ class AVIDump
};

static bool Start(int w, int h, DumpFormat format);
static void AddFrame(const u8* data, int width, int height);
static void AddFrame(const u8* data, int width, int height, int stride);
static void Stop();
static void DoState();
};
27 changes: 5 additions & 22 deletions Source/Core/VideoCommon/RenderBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,31 +555,20 @@ bool Renderer::IsFrameDumping()
return false;
}

void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format,
void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, 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;
m_last_framedump_stride = stride;

// 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);
m_frame_data.assign(data, data + stride * h);

if (!m_last_frame_dumped)
{
Expand All @@ -599,21 +588,15 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat f
{
if (swap_upside_down)
FlipImageData(m_frame_data.data(), w, h, 4);
AVIDump::AddFrame(m_frame_data.data(), w, h);
AVIDump::AddFrame(m_frame_data.data(), w, h, stride);
}

m_last_frame_dumped = true;
#endif
}

void Renderer::RepeatFrameDumpFrame()
void Renderer::FinishFrameData()
{
#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)
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/VideoCommon/RenderBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ class Renderer
static void RecordVideoMemory();

bool IsFrameDumping();
void DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format,
void DumpFrameData(const u8* data, int w, int h, int stride, AVIDump::DumpFormat format,
bool swap_upside_down = false);
void RepeatFrameDumpFrame();
void FinishFrameData();

static volatile bool s_bScreenshot;
static std::mutex s_criticalScreenshot;
Expand Down Expand Up @@ -194,6 +194,7 @@ class Renderer
bool m_last_frame_dumped = false;
int m_last_framedump_width = 0;
int m_last_framedump_height = 0;
int m_last_framedump_stride = 0;
AVIDump::DumpFormat m_last_framedump_format;
};

Expand Down