VideoCommon: Add method for calculating full-scale framedump rectangles

This commit is contained in:
Stenzek 2016-11-10 22:36:11 +10:00
parent 6db0ee9561
commit adc22a5e20
2 changed files with 74 additions and 11 deletions

View File

@ -18,6 +18,7 @@
#include <mutex>
#include <string>
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Event.h"
#include "Common/FileUtil.h"
@ -449,6 +450,76 @@ void Renderer::DrawDebugText()
g_renderer->RenderText(final_yellow, 20, 20, 0xFFFFFF00);
}
float Renderer::CalculateDrawAspectRatio(int target_width, int target_height)
{
// The dimensions are the sizes that are used to create the EFB/backbuffer textures, so
// they should always be greater than zero.
_assert_(target_width > 0 && target_height > 0);
if (g_ActiveConfig.iAspectRatio == ASPECT_STRETCH)
{
// If stretch is enabled, we prefer the aspect ratio of the window.
return (static_cast<float>(target_width) / static_cast<float>(target_height)) /
(static_cast<float>(s_backbuffer_width) / static_cast<float>(s_backbuffer_height));
}
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
if (g_ActiveConfig.iAspectRatio == ASPECT_ANALOG_WIDE ||
(g_ActiveConfig.iAspectRatio != ASPECT_ANALOG && Core::g_aspect_wide))
{
return (static_cast<float>(target_width) / static_cast<float>(target_height)) /
AspectToWidescreen(VideoInterface::GetAspectRatio());
}
else
{
return (static_cast<float>(target_width) / static_cast<float>(target_height)) /
VideoInterface::GetAspectRatio();
}
}
TargetRectangle Renderer::CalculateFrameDumpDrawRectangle()
{
// No point including any borders in the frame dump image, since they'd have to be cropped anyway.
TargetRectangle rc;
rc.left = 0;
rc.top = 0;
// If full-resolution frame dumping is disabled, just use the window draw rectangle.
// Also do this if RealXFB is enabled, since the image has been downscaled for the XFB copy
// anyway, and there's no point writing an upscaled frame with no filtering.
if (!g_ActiveConfig.bInternalResolutionFrameDumps || g_ActiveConfig.RealXFBEnabled())
{
// But still remove the borders, since the caller expects this.
rc.right = target_rc.GetWidth();
rc.bottom = target_rc.GetHeight();
return rc;
}
// Grab the dimensions of the EFB textures, we scale either of these depending on the ratio.
unsigned int efb_width, efb_height;
g_framebuffer_manager->GetTargetSize(&efb_width, &efb_height);
// Scale either the width or height depending the content aspect ratio.
// This way we preserve as much resolution as possible when scaling.
float ratio = CalculateDrawAspectRatio(efb_width, efb_height);
float draw_width, draw_height;
if (ratio >= 1.0f)
{
// Preserve horizontal resolution, scale vertically.
draw_width = static_cast<float>(efb_width);
draw_height = static_cast<float>(efb_height) * ratio;
}
else
{
// Preserve vertical resolution, scale horizontally.
draw_width = static_cast<float>(efb_width) / ratio;
draw_height = static_cast<float>(efb_height);
}
rc.right = static_cast<int>(std::ceil(draw_width));
rc.bottom = static_cast<int>(std::ceil(draw_height));
return rc;
}
void Renderer::UpdateDrawRectangle()
{
float FloatGLWidth = static_cast<float>(s_backbuffer_width);
@ -511,17 +582,7 @@ void Renderer::UpdateDrawRectangle()
// Check for force-settings and override.
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
float Ratio;
if (g_ActiveConfig.iAspectRatio == ASPECT_ANALOG_WIDE ||
(g_ActiveConfig.iAspectRatio != ASPECT_ANALOG && Core::g_aspect_wide))
{
Ratio = (WinWidth / WinHeight) / AspectToWidescreen(VideoInterface::GetAspectRatio());
}
else
{
Ratio = (WinWidth / WinHeight) / VideoInterface::GetAspectRatio();
}
float Ratio = CalculateDrawAspectRatio(s_backbuffer_width, s_backbuffer_height);
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH)
{
if (Ratio > 1.0f)

View File

@ -93,6 +93,8 @@ public:
virtual TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) = 0;
static const TargetRectangle& GetTargetRectangle() { return target_rc; }
static float CalculateDrawAspectRatio(int target_width, int target_height);
static TargetRectangle CalculateFrameDumpDrawRectangle();
static void UpdateDrawRectangle();
// Use this to convert a single target rectangle to two stereo rectangles