mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	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