Merge pull request #5312 from ligfx/cleanupupdatedrawrectangle

RenderBase: clean up UpdateDrawRectangle
This commit is contained in:
shuffle2 2017-06-05 20:03:56 -07:00 committed by GitHub
commit 98eb192226
2 changed files with 55 additions and 76 deletions

View File

@ -456,29 +456,23 @@ void Renderer::DrawDebugText()
RenderText(final_yellow, 20, 20, 0xFFFFFF00); RenderText(final_yellow, 20, 20, 0xFFFFFF00);
} }
float Renderer::CalculateDrawAspectRatio(int target_width, int target_height) const float Renderer::CalculateDrawAspectRatio() const
{ {
// 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 (g_ActiveConfig.iAspectRatio == ASPECT_STRETCH)
{ {
// If stretch is enabled, we prefer the aspect ratio of the window. // If stretch is enabled, we prefer the aspect ratio of the window.
return (static_cast<float>(target_width) / static_cast<float>(target_height)) / return (static_cast<float>(m_backbuffer_width) / static_cast<float>(m_backbuffer_height));
(static_cast<float>(m_backbuffer_width) / static_cast<float>(m_backbuffer_height));
} }
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio // The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
if (g_ActiveConfig.iAspectRatio == ASPECT_ANALOG_WIDE || if (g_ActiveConfig.iAspectRatio == ASPECT_ANALOG_WIDE ||
(g_ActiveConfig.iAspectRatio != ASPECT_ANALOG && m_aspect_wide)) (g_ActiveConfig.iAspectRatio != ASPECT_ANALOG && m_aspect_wide))
{ {
return (static_cast<float>(target_width) / static_cast<float>(target_height)) / return AspectToWidescreen(VideoInterface::GetAspectRatio());
AspectToWidescreen(VideoInterface::GetAspectRatio());
} }
else else
{ {
return (static_cast<float>(target_width) / static_cast<float>(target_height)) / return VideoInterface::GetAspectRatio();
VideoInterface::GetAspectRatio();
} }
} }
@ -487,15 +481,14 @@ std::tuple<float, float> Renderer::ScaleToDisplayAspectRatio(const int width,
{ {
// Scale either the width or height depending the content aspect ratio. // Scale either the width or height depending the content aspect ratio.
// This way we preserve as much resolution as possible when scaling. // This way we preserve as much resolution as possible when scaling.
float ratio = CalculateDrawAspectRatio(width, height); float scaled_width = static_cast<float>(width);
if (ratio >= 1.0f) float scaled_height = static_cast<float>(height);
{ const float draw_aspect = CalculateDrawAspectRatio();
// Preserve horizontal resolution, scale vertically. if (scaled_width / scaled_height >= draw_aspect)
return std::make_tuple(static_cast<float>(width), static_cast<float>(height) * ratio); scaled_height = scaled_width / draw_aspect;
} else
scaled_width = scaled_height * draw_aspect;
// Preserve vertical resolution, scale horizontally. return std::make_tuple(scaled_width, scaled_height);
return std::make_tuple(static_cast<float>(width) / ratio, static_cast<float>(height));
} }
TargetRectangle Renderer::CalculateFrameDumpDrawRectangle() const TargetRectangle Renderer::CalculateFrameDumpDrawRectangle() const
@ -530,14 +523,9 @@ TargetRectangle Renderer::CalculateFrameDumpDrawRectangle() const
void Renderer::UpdateDrawRectangle() void Renderer::UpdateDrawRectangle()
{ {
float FloatGLWidth = static_cast<float>(m_backbuffer_width);
float FloatGLHeight = static_cast<float>(m_backbuffer_height);
float FloatXOffset = 0;
float FloatYOffset = 0;
// The rendering window size // The rendering window size
const float WinWidth = FloatGLWidth; const float win_width = static_cast<float>(m_backbuffer_width);
const float WinHeight = FloatGLHeight; const float win_height = static_cast<float>(m_backbuffer_height);
// Update aspect ratio hack values // Update aspect ratio hack values
// Won't take effect until next frame // Won't take effect until next frame
@ -552,7 +540,7 @@ void Renderer::UpdateDrawRectangle()
switch (g_ActiveConfig.iAspectRatio) switch (g_ActiveConfig.iAspectRatio)
{ {
case ASPECT_STRETCH: case ASPECT_STRETCH:
target_aspect = WinWidth / WinHeight; target_aspect = win_width / win_height;
break; break;
case ASPECT_ANALOG: case ASPECT_ANALOG:
target_aspect = VideoInterface::GetAspectRatio(); target_aspect = VideoInterface::GetAspectRatio();
@ -587,67 +575,57 @@ void Renderer::UpdateDrawRectangle()
g_Config.fAspectRatioHackH = 1; g_Config.fAspectRatioHackH = 1;
} }
// Check for force-settings and override. float draw_width, draw_height, crop_width, crop_height;
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio // get the picture aspect ratio
float Ratio = CalculateDrawAspectRatio(m_backbuffer_width, m_backbuffer_height); draw_width = crop_width = CalculateDrawAspectRatio();
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH) draw_height = crop_height = 1;
// crop the picture to a standard aspect ratio
if (g_ActiveConfig.bCrop && g_ActiveConfig.iAspectRatio != ASPECT_STRETCH)
{ {
if (Ratio >= 0.995f && Ratio <= 1.005f) float expected_aspect = (g_ActiveConfig.iAspectRatio == ASPECT_ANALOG_WIDE ||
(g_ActiveConfig.iAspectRatio != ASPECT_ANALOG && m_aspect_wide)) ?
(16.0f / 9.0f) :
(4.0f / 3.0f);
if (crop_width / crop_height >= expected_aspect)
{ {
// If we're very close already, don't scale. // the picture is flatter than it should be
Ratio = 1.0f; crop_width = crop_height * expected_aspect;
} }
else if (Ratio > 1.0f)
{
// Scale down and center in the X direction.
FloatGLWidth /= Ratio;
FloatXOffset = (WinWidth - FloatGLWidth) / 2.0f;
}
// The window is too high, we have to limit the height
else else
{ {
// Scale down and center in the Y direction. // the picture is skinnier than it should be
FloatGLHeight *= Ratio; crop_height = crop_width / expected_aspect;
FloatYOffset = FloatYOffset + (WinHeight - FloatGLHeight) / 2.0f;
} }
} }
// ----------------------------------------------------------------------- // scale the picture to fit the rendering window
// Crop the picture from Analog to 4:3 or from Analog (Wide) to 16:9. if (win_width / win_height >= crop_width / crop_height)
// Output: FloatGLWidth, FloatGLHeight, FloatXOffset, FloatYOffset
// ------------------
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH && g_ActiveConfig.bCrop)
{ {
Ratio = (4.0f / 3.0f) / VideoInterface::GetAspectRatio(); // the window is flatter than the picture
if (Ratio <= 1.0f) draw_width *= win_height / crop_height;
crop_width *= win_height / crop_height;
draw_height *= win_height / crop_height;
crop_height = win_height;
}
else
{ {
Ratio = 1.0f / Ratio; // the window is skinnier than the picture
} draw_width *= win_width / crop_width;
// The width and height we will add (calculate this before FloatGLWidth and FloatGLHeight is draw_height *= win_width / crop_width;
// adjusted) crop_height *= win_width / crop_width;
float IncreasedWidth = (Ratio - 1.0f) * FloatGLWidth; crop_width = win_width;
float IncreasedHeight = (Ratio - 1.0f) * FloatGLHeight;
// The new width and height
FloatGLWidth = FloatGLWidth * Ratio;
FloatGLHeight = FloatGLHeight * Ratio;
// Adjust the X and Y offset
FloatXOffset = FloatXOffset - (IncreasedWidth * 0.5f);
FloatYOffset = FloatYOffset - (IncreasedHeight * 0.5f);
} }
int XOffset = (int)(FloatXOffset + 0.5f); // ensure divisibility by 4 to make it compatible with all the video encoders
int YOffset = (int)(FloatYOffset + 0.5f); draw_width = std::ceil(draw_width) - static_cast<int>(std::ceil(draw_width)) % 4;
int iWhidth = (int)ceil(FloatGLWidth); draw_height = std::ceil(draw_height) - static_cast<int>(std::ceil(draw_height)) % 4;
int iHeight = (int)ceil(FloatGLHeight);
iWhidth -=
iWhidth % 4; // ensure divisibility by 4 to make it compatible with all the video encoders
iHeight -= iHeight % 4;
m_target_rectangle.left = XOffset; m_target_rectangle.left = static_cast<int>(std::round(win_width / 2.0 - draw_width / 2.0));
m_target_rectangle.top = YOffset; m_target_rectangle.top = static_cast<int>(std::round(win_height / 2.0 - draw_height / 2.0));
m_target_rectangle.right = XOffset + iWhidth; m_target_rectangle.right = m_target_rectangle.left + static_cast<int>(draw_width);
m_target_rectangle.bottom = YOffset + iHeight; m_target_rectangle.bottom = m_target_rectangle.top + static_cast<int>(draw_height);
} }
void Renderer::SetWindowSize(int width, int height) void Renderer::SetWindowSize(int width, int height)

View File

@ -93,7 +93,8 @@ public:
virtual TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) = 0; virtual TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) = 0;
const TargetRectangle& GetTargetRectangle() const { return m_target_rectangle; } const TargetRectangle& GetTargetRectangle() const { return m_target_rectangle; }
float CalculateDrawAspectRatio(int target_width, int target_height) const; float CalculateDrawAspectRatio() const;
std::tuple<float, float> ScaleToDisplayAspectRatio(int width, int height) const; std::tuple<float, float> ScaleToDisplayAspectRatio(int width, int height) const;
TargetRectangle CalculateFrameDumpDrawRectangle() const; TargetRectangle CalculateFrameDumpDrawRectangle() const;
void UpdateDrawRectangle(); void UpdateDrawRectangle();