Add "Separate Windows" LayoutOption (#6177)

This commit is contained in:
Ameer J 2022-11-17 10:37:30 -05:00 committed by GitHub
parent 4f715b6718
commit f44c95d638
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 358 additions and 124 deletions

View file

@ -9,11 +9,20 @@
#include "video_core/swrasterizer/swrasterizer.h"
#include "video_core/video_core.h"
RendererBase::RendererBase(Frontend::EmuWindow& window) : render_window{window} {}
RendererBase::RendererBase(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window_)
: render_window{window}, secondary_window{secondary_window_} {}
RendererBase::~RendererBase() = default;
void RendererBase::UpdateCurrentFramebufferLayout(bool is_portrait_mode) {
const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout();
render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height, is_portrait_mode);
const auto update_layout = [is_portrait_mode](Frontend::EmuWindow& window) {
const Layout::FramebufferLayout& layout = window.GetFramebufferLayout();
window.UpdateCurrentFramebufferLayout(layout.width, layout.height, is_portrait_mode);
};
update_layout(render_window);
if (secondary_window) {
update_layout(*secondary_window);
}
}
void RendererBase::RefreshRasterizerSetting() {

View file

@ -15,7 +15,7 @@ class EmuWindow;
class RendererBase : NonCopyable {
public:
explicit RendererBase(Frontend::EmuWindow& window);
explicit RendererBase(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window);
virtual ~RendererBase();
/// Initialize the renderer
@ -29,7 +29,10 @@ public:
/// Draws the latest frame to the window waiting timeout_ms for a frame to arrive (Renderer
/// specific implementation)
virtual void TryPresent(int timeout_ms) = 0;
virtual void TryPresent(int timeout_ms, bool is_secondary) = 0;
virtual void TryPresent(int timeout_ms) {
TryPresent(timeout_ms, false);
}
/// Prepares for video dumping (e.g. create necessary buffers, etc)
virtual void PrepareVideoDumping() = 0;
@ -67,7 +70,8 @@ public:
void Sync();
protected:
Frontend::EmuWindow& render_window; ///< Reference to the render window handle.
Frontend::EmuWindow& render_window; ///< Reference to the render window handle.
Frontend::EmuWindow* secondary_window; ///< Reference to the secondary render window handle.
std::unique_ptr<VideoCore::RasterizerInterface> rasterizer;
f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer
int m_current_frame = 0; ///< Current frame, should be set by the renderer

View file

@ -352,10 +352,13 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
return matrix;
}
RendererOpenGL::RendererOpenGL(Frontend::EmuWindow& window)
: RendererBase{window}, frame_dumper(Core::System::GetInstance().VideoDumper(), window) {
RendererOpenGL::RendererOpenGL(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window)
: RendererBase{window, secondary_window},
frame_dumper(Core::System::GetInstance().VideoDumper(), window) {
window.mailbox = std::make_unique<OGLTextureMailbox>();
if (secondary_window) {
secondary_window->mailbox = std::make_unique<OGLTextureMailbox>();
}
frame_dumper.mailbox = std::make_unique<OGLVideoDumpingMailbox>();
}
@ -374,9 +377,17 @@ void RendererOpenGL::SwapBuffers() {
RenderScreenshot();
const auto& layout = render_window.GetFramebufferLayout();
RenderToMailbox(layout, render_window.mailbox, false);
const auto& main_layout = render_window.GetFramebufferLayout();
RenderToMailbox(main_layout, render_window.mailbox, false);
#ifndef ANDROID
if (Settings::values.layout_option == Settings::LayoutOption::SeparateWindows) {
ASSERT(secondary_window);
const auto& secondary_layout = secondary_window->GetFramebufferLayout();
RenderToMailbox(secondary_layout, secondary_window->mailbox, false);
secondary_window->PollEvents();
}
#endif
if (frame_dumper.IsDumping()) {
try {
RenderToMailbox(frame_dumper.GetLayout(), frame_dumper.mailbox, true);
@ -1112,9 +1123,10 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
}
}
void RendererOpenGL::TryPresent(int timeout_ms) {
const auto& layout = render_window.GetFramebufferLayout();
auto frame = render_window.mailbox->TryGetPresentFrame(timeout_ms);
void RendererOpenGL::TryPresent(int timeout_ms, bool is_secondary) {
const auto& window = is_secondary ? *secondary_window : render_window;
const auto& layout = window.GetFramebufferLayout();
auto frame = window.mailbox->TryGetPresentFrame(timeout_ms);
if (!frame) {
LOG_DEBUG(Render_OpenGL, "TryGetPresentFrame returned no frame to present");
return;
@ -1127,7 +1139,7 @@ void RendererOpenGL::TryPresent(int timeout_ms) {
// Recreate the presentation FBO if the color attachment was changed
if (frame->color_reloaded) {
LOG_DEBUG(Render_OpenGL, "Reloading present frame");
render_window.mailbox->ReloadPresentFrame(frame, layout.width, layout.height);
window.mailbox->ReloadPresentFrame(frame, layout.width, layout.height);
}
glWaitSync(frame->render_fence, 0, GL_TIMEOUT_IGNORED);
// INTEL workaround.

View file

@ -56,7 +56,7 @@ struct PresentationTexture {
class RendererOpenGL : public RendererBase {
public:
explicit RendererOpenGL(Frontend::EmuWindow& window);
explicit RendererOpenGL(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window);
~RendererOpenGL() override;
/// Initialize the renderer
@ -70,7 +70,7 @@ public:
/// Draws the latest frame from texture mailbox to the currently bound draw framebuffer in this
/// context
void TryPresent(int timeout_ms) override;
void TryPresent(int timeout_ms, bool is_secondary) override;
/// Prepares for video dumping (e.g. create necessary buffers, etc)
void PrepareVideoDumping() override;

View file

@ -39,13 +39,14 @@ Layout::FramebufferLayout g_screenshot_framebuffer_layout;
Memory::MemorySystem* g_memory;
/// Initialize the video core
ResultStatus Init(Frontend::EmuWindow& emu_window, Memory::MemorySystem& memory) {
ResultStatus Init(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondary_window,
Memory::MemorySystem& memory) {
g_memory = &memory;
Pica::Init();
OpenGL::GLES = Settings::values.use_gles;
g_renderer = std::make_unique<OpenGL::RendererOpenGL>(emu_window);
g_renderer = std::make_unique<OpenGL::RendererOpenGL>(emu_window, secondary_window);
ResultStatus result = g_renderer->Init();
if (result != ResultStatus::Success) {

View file

@ -54,7 +54,8 @@ enum class ResultStatus {
};
/// Initialize the video core
ResultStatus Init(Frontend::EmuWindow& emu_window, Memory::MemorySystem& memory);
ResultStatus Init(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondary_window,
Memory::MemorySystem& memory);
/// Shutdown the video core
void Shutdown();