Add "Separate Windows" LayoutOption (#6177)
This commit is contained in:
parent
4f715b6718
commit
f44c95d638
24 changed files with 358 additions and 124 deletions
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue