summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/RenderBase.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2019-04-28 16:53:16 +1000
committerStenzek <stenzek@gmail.com>2019-04-28 23:31:57 +1000
commit3c64f0c6165f7f998952c9a4829970b143f930cb (patch)
tree4ebbc7bcf75a94f65c7ad9a109001c2622482f36 /Source/Core/VideoCommon/RenderBase.cpp
parentd2d8d7ce90f92bb45e2d8b645ec72f104fee5e6b (diff)
Renderer: Adjust source rectangle when crop would draw off screen
This prevents us from requiring an oversized and/or negative viewport by shrinking the source rectangle instead.
Diffstat (limited to 'Source/Core/VideoCommon/RenderBase.cpp')
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp44
1 files changed, 40 insertions, 4 deletions
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index 523a681884..039da1f189 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -561,6 +561,40 @@ float Renderer::CalculateDrawAspectRatio() const
}
}
+void Renderer::AdjustRectanglesToFitBounds(MathUtil::Rectangle<int>* target_rect,
+ MathUtil::Rectangle<int>* source_rect, int fb_width,
+ int fb_height)
+{
+ const int orig_target_width = target_rect->GetWidth();
+ const int orig_target_height = target_rect->GetHeight();
+ const int orig_source_width = source_rect->GetWidth();
+ const int orig_source_height = source_rect->GetHeight();
+ if (target_rect->left < 0)
+ {
+ const int offset = -target_rect->left;
+ target_rect->left = 0;
+ source_rect->left += offset * orig_source_width / orig_target_width;
+ }
+ if (target_rect->right > fb_width)
+ {
+ const int offset = target_rect->right - fb_width;
+ target_rect->right -= offset;
+ source_rect->right -= offset * orig_source_width / orig_target_width;
+ }
+ if (target_rect->top < 0)
+ {
+ const int offset = -target_rect->top;
+ target_rect->top = 0;
+ source_rect->top += offset * orig_source_height / orig_target_height;
+ }
+ if (target_rect->bottom > fb_height)
+ {
+ const int offset = target_rect->bottom - fb_height;
+ target_rect->right -= offset;
+ source_rect->right -= offset * orig_source_height / orig_target_height;
+ }
+}
+
bool Renderer::IsHeadless() const
{
return true;
@@ -1287,19 +1321,21 @@ void Renderer::Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u6
void Renderer::RenderXFBToScreen(const AbstractTexture* texture, const MathUtil::Rectangle<int>& rc)
{
- const auto target_rc = GetTargetRectangle();
+ auto adjusted_rc = rc;
+ auto target_rc = GetTargetRectangle();
+ AdjustRectanglesToFitBounds(&target_rc, &adjusted_rc, m_backbuffer_width, m_backbuffer_height);
if (g_ActiveConfig.stereo_mode == StereoMode::SBS ||
g_ActiveConfig.stereo_mode == StereoMode::TAB)
{
MathUtil::Rectangle<int> left_rc, right_rc;
std::tie(left_rc, right_rc) = ConvertStereoRectangle(target_rc);
- m_post_processor->BlitFromTexture(left_rc, rc, texture, 0);
- m_post_processor->BlitFromTexture(right_rc, rc, texture, 1);
+ m_post_processor->BlitFromTexture(left_rc, adjusted_rc, texture, 0);
+ m_post_processor->BlitFromTexture(right_rc, adjusted_rc, texture, 1);
}
else
{
- m_post_processor->BlitFromTexture(target_rc, rc, texture, 0);
+ m_post_processor->BlitFromTexture(target_rc, adjusted_rc, texture, 0);
}
}