summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/Render.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@users.noreply.github.com>2018-02-20 01:19:45 +1000
committerGitHub <noreply@github.com>2018-02-20 01:19:45 +1000
commit93c502fef8980bf6f6db7316738857bb0818debf (patch)
tree7e14390a62a600c8ec89ad39a77919748d6152f1 /Source/Core/VideoBackends/OGL/Render.cpp
parent456c2f42c350e15402eea169a2cc87878327c1fc (diff)
parent0dddaf9d7d0837a574c6e8d255bebb3947f09a0e (diff)
Merge pull request #6330 from stenzek/resizing
Improve handling of surface change/resize events in graphics backends
Diffstat (limited to 'Source/Core/VideoBackends/OGL/Render.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/Render.cpp108
1 files changed, 43 insertions, 65 deletions
diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp
index 22bfd58982..7e11d06574 100644
--- a/Source/Core/VideoBackends/OGL/Render.cpp
+++ b/Source/Core/VideoBackends/OGL/Render.cpp
@@ -845,12 +845,10 @@ std::unique_ptr<AbstractStagingTexture> Renderer::CreateStagingTexture(StagingTe
void Renderer::RenderText(const std::string& text, int left, int top, u32 color)
{
- u32 backbuffer_width = std::max(GLInterface->GetBackBufferWidth(), 1u);
- u32 backbuffer_height = std::max(GLInterface->GetBackBufferHeight(), 1u);
-
- s_raster_font->printMultilineText(text, left * 2.0f / static_cast<float>(backbuffer_width) - 1.0f,
- 1.0f - top * 2.0f / static_cast<float>(backbuffer_height), 0,
- backbuffer_width, backbuffer_height, color);
+ s_raster_font->printMultilineText(text,
+ left * 2.0f / static_cast<float>(m_backbuffer_width) - 1.0f,
+ 1.0f - top * 2.0f / static_cast<float>(m_backbuffer_height), 0,
+ m_backbuffer_width, m_backbuffer_height, color);
}
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
@@ -1319,33 +1317,36 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
ResetAPIState();
+ // Do our OSD callbacks
+ OSD::DoCallbacks(OSD::CallbackType::OnFrame);
+
+ // Check if we need to render to a new surface.
+ CheckForSurfaceChange();
+ CheckForSurfaceResize();
UpdateDrawRectangle();
TargetRectangle flipped_trc = GetTargetRectangle();
-
- // Flip top and bottom for some reason; TODO: Fix the code to suck less?
std::swap(flipped_trc.top, flipped_trc.bottom);
- // Do our OSD callbacks
- OSD::DoCallbacks(OSD::CallbackType::OnFrame);
-
// Skip screen rendering when running in headless mode.
if (!IsHeadless())
{
- // Copy the framebuffer to screen.
+ // Clear the framebuffer before drawing anything.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ // Copy the framebuffer to screen.
BlitScreen(sourceRc, flipped_trc, xfb_texture->GetRawTexIdentifier(),
xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
- // Finish up the current frame, print some stats
+ // Render OSD messages.
+ glViewport(0, 0, m_backbuffer_width, m_backbuffer_height);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- // Reset viewport for drawing text
- glViewport(0, 0, GLInterface->GetBackBufferWidth(), GLInterface->GetBackBufferHeight());
DrawDebugText();
OSD::DrawMessages();
- // Copy the rendered frame to the real window.
+ // Swap the back and front buffers, presenting the image.
GLInterface->Swap();
}
else
@@ -1355,32 +1356,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
glFlush();
}
-#ifdef ANDROID
- // Handle surface changes on Android.
- if (m_surface_needs_change.IsSet())
- {
- GLInterface->UpdateHandle(m_new_surface_handle);
- GLInterface->UpdateSurface();
- m_surface_handle = m_new_surface_handle;
- m_new_surface_handle = nullptr;
- m_surface_needs_change.Clear();
- m_surface_changed.Set();
- }
-#endif
-
- GLInterface->Update();
-
// Was the size changed since the last frame?
- bool window_resized = false;
- int window_width = static_cast<int>(std::max(GLInterface->GetBackBufferWidth(), 1u));
- int window_height = static_cast<int>(std::max(GLInterface->GetBackBufferHeight(), 1u));
- if (window_width != m_backbuffer_width || window_height != m_backbuffer_height)
- {
- window_resized = true;
- m_backbuffer_width = window_width;
- m_backbuffer_height = window_height;
- }
-
bool target_size_changed = CalculateTargetSize();
bool stencil_buffer_enabled =
static_cast<FramebufferManager*>(g_framebuffer_manager.get())->HasStencilBuffer();
@@ -1390,10 +1366,6 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
stencil_buffer_enabled != BoundingBox::NeedsStencilBuffer() ||
s_last_stereo_mode != (g_ActiveConfig.stereo_mode != StereoMode::Off);
- if (window_resized || fb_needs_update)
- {
- UpdateDrawRectangle();
- }
if (fb_needs_update)
{
s_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off;
@@ -1413,13 +1385,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
g_framebuffer_manager = std::make_unique<FramebufferManager>(
m_target_width, m_target_height, s_MSAASamples, BoundingBox::NeedsStencilBuffer());
BoundingBox::SetTargetSizeChanged(m_target_width, m_target_height);
- }
-
- // Clear framebuffer
- if (!IsHeadless())
- {
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ UpdateDrawRectangle();
}
if (s_vsync != g_ActiveConfig.IsVSync())
@@ -1460,6 +1426,30 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
ClearEFBCache();
}
+void Renderer::CheckForSurfaceChange()
+{
+ if (!m_surface_changed.TestAndClear())
+ return;
+
+ m_surface_handle = m_new_surface_handle;
+ m_new_surface_handle = nullptr;
+ GLInterface->UpdateHandle(m_surface_handle);
+ GLInterface->UpdateSurface();
+
+ // With a surface change, the window likely has new dimensions.
+ m_backbuffer_width = GLInterface->GetBackBufferWidth();
+ m_backbuffer_height = GLInterface->GetBackBufferHeight();
+}
+
+void Renderer::CheckForSurfaceResize()
+{
+ if (!m_surface_resized.TestAndClear())
+ return;
+
+ m_backbuffer_width = m_new_backbuffer_width;
+ m_backbuffer_height = m_new_backbuffer_height;
+}
+
void Renderer::DrawEFB(GLuint framebuffer, const TargetRectangle& target_rc,
const TargetRectangle& source_rc)
{
@@ -1577,16 +1567,4 @@ void Renderer::SetInterlacingMode()
{
// TODO
}
-
-void Renderer::ChangeSurface(void* new_surface_handle)
-{
-// Win32 polls the window size when redrawing, X11 runs an event loop in another thread.
-// This is only necessary for Android at this point, although handling resizes here
-// would be more efficient than polling.
-#ifdef ANDROID
- m_new_surface_handle = new_surface_handle;
- m_surface_needs_change.Set();
- m_surface_changed.Wait();
-#endif
-}
}