summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/frontend/emu_window.h3
-rw-r--r--src/yuzu/bootmanager.cpp3
-rw-r--r--src/yuzu/bootmanager.h3
-rw-r--r--src/yuzu_cmd/CMakeLists.txt2
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp174
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.h26
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp154
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h34
-rw-r--r--src/yuzu_cmd/yuzu.cpp3
9 files changed, 216 insertions, 186 deletions
diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h
index e2c290dc1..4a9912641 100644
--- a/src/core/frontend/emu_window.h
+++ b/src/core/frontend/emu_window.h
@@ -169,8 +169,7 @@ private:
169 * For the request to be honored, EmuWindow implementations will usually reimplement this 169 * For the request to be honored, EmuWindow implementations will usually reimplement this
170 * function. 170 * function.
171 */ 171 */
172 virtual void OnMinimalClientAreaChangeRequest( 172 virtual void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned>) {
173 const std::pair<unsigned, unsigned>& minimal_size) {
174 // By default, ignore this request and do nothing. 173 // By default, ignore this request and do nothing.
175 } 174 }
176 175
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index eeee603d1..9e420b359 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -440,8 +440,7 @@ void GRenderWindow::CaptureScreenshot(u16 res_scale, const QString& screenshot_p
440 layout); 440 layout);
441} 441}
442 442
443void GRenderWindow::OnMinimalClientAreaChangeRequest( 443void GRenderWindow::OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) {
444 const std::pair<unsigned, unsigned>& minimal_size) {
445 setMinimumSize(minimal_size.first, minimal_size.second); 444 setMinimumSize(minimal_size.first, minimal_size.second);
446} 445}
447 446
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 3df33aca1..7f9f8e8e3 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -162,8 +162,7 @@ private:
162 void TouchUpdateEvent(const QTouchEvent* event); 162 void TouchUpdateEvent(const QTouchEvent* event);
163 void TouchEndEvent(); 163 void TouchEndEvent();
164 164
165 void OnMinimalClientAreaChangeRequest( 165 void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) override;
166 const std::pair<unsigned, unsigned>& minimal_size) override;
167 166
168 QWidget* container = nullptr; 167 QWidget* container = nullptr;
169 GGLWidgetInternal* child = nullptr; 168 GGLWidgetInternal* child = nullptr;
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt
index 297dab653..b5f06ab9e 100644
--- a/src/yuzu_cmd/CMakeLists.txt
+++ b/src/yuzu_cmd/CMakeLists.txt
@@ -4,6 +4,8 @@ add_executable(yuzu-cmd
4 config.cpp 4 config.cpp
5 config.h 5 config.h
6 default_ini.h 6 default_ini.h
7 emu_window/emu_window_sdl2_gl.cpp
8 emu_window/emu_window_sdl2_gl.h
7 emu_window/emu_window_sdl2.cpp 9 emu_window/emu_window_sdl2.cpp
8 emu_window/emu_window_sdl2.h 10 emu_window/emu_window_sdl2.h
9 resource.h 11 resource.h
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 8f104062d..a6edc089a 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -2,53 +2,27 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
6#include <cstdlib>
7#include <string>
8#define SDL_MAIN_HANDLED
9#include <SDL.h> 5#include <SDL.h>
10#include <fmt/format.h>
11#include <glad/glad.h>
12#include "common/logging/log.h" 6#include "common/logging/log.h"
13#include "common/scm_rev.h"
14#include "common/string_util.h"
15#include "core/settings.h"
16#include "input_common/keyboard.h" 7#include "input_common/keyboard.h"
17#include "input_common/main.h" 8#include "input_common/main.h"
18#include "input_common/motion_emu.h" 9#include "input_common/motion_emu.h"
19#include "input_common/sdl/sdl.h" 10#include "input_common/sdl/sdl.h"
20#include "yuzu_cmd/emu_window/emu_window_sdl2.h" 11#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
21 12
22class SDLGLContext : public Core::Frontend::GraphicsContext { 13EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
23public: 14 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
24 explicit SDLGLContext() { 15 LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
25 // create a hidden window to make the shared context against 16 exit(1);
26 window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, // x position
27 SDL_WINDOWPOS_UNDEFINED, // y position
28 Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height,
29 SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
30 context = SDL_GL_CreateContext(window);
31 }
32
33 ~SDLGLContext() {
34 SDL_GL_DeleteContext(context);
35 SDL_DestroyWindow(window);
36 }
37
38 void MakeCurrent() override {
39 SDL_GL_MakeCurrent(window, context);
40 }
41
42 void DoneCurrent() override {
43 SDL_GL_MakeCurrent(window, nullptr);
44 } 17 }
18 InputCommon::Init();
19 SDL_SetMainReady();
20}
45 21
46 void SwapBuffers() override {} 22EmuWindow_SDL2::~EmuWindow_SDL2() {
47 23 InputCommon::Shutdown();
48private: 24 SDL_Quit();
49 SDL_Window* window; 25}
50 SDL_GLContext context;
51};
52 26
53void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { 27void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
54 TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); 28 TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
@@ -139,112 +113,6 @@ void EmuWindow_SDL2::Fullscreen() {
139 SDL_MaximizeWindow(render_window); 113 SDL_MaximizeWindow(render_window);
140} 114}
141 115
142bool EmuWindow_SDL2::SupportsRequiredGLExtensions() {
143 std::vector<std::string> unsupported_ext;
144
145 if (!GLAD_GL_ARB_direct_state_access)
146 unsupported_ext.push_back("ARB_direct_state_access");
147 if (!GLAD_GL_ARB_vertex_type_10f_11f_11f_rev)
148 unsupported_ext.push_back("ARB_vertex_type_10f_11f_11f_rev");
149 if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge)
150 unsupported_ext.push_back("ARB_texture_mirror_clamp_to_edge");
151 if (!GLAD_GL_ARB_multi_bind)
152 unsupported_ext.push_back("ARB_multi_bind");
153
154 // Extensions required to support some texture formats.
155 if (!GLAD_GL_EXT_texture_compression_s3tc)
156 unsupported_ext.push_back("EXT_texture_compression_s3tc");
157 if (!GLAD_GL_ARB_texture_compression_rgtc)
158 unsupported_ext.push_back("ARB_texture_compression_rgtc");
159 if (!GLAD_GL_ARB_depth_buffer_float)
160 unsupported_ext.push_back("ARB_depth_buffer_float");
161
162 for (const std::string& ext : unsupported_ext)
163 LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext);
164
165 return unsupported_ext.empty();
166}
167
168EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
169 // Initialize the window
170 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
171 LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
172 exit(1);
173 }
174
175 InputCommon::Init();
176
177 SDL_SetMainReady();
178
179 const SDL_GLprofile profile = Settings::values.use_compatibility_profile
180 ? SDL_GL_CONTEXT_PROFILE_COMPATIBILITY
181 : SDL_GL_CONTEXT_PROFILE_CORE;
182
183 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
184 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
185 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile);
186 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
187 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
188 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
189 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
190 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
191 SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
192
193 std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_fullname,
194 Common::g_scm_branch, Common::g_scm_desc);
195 render_window =
196 SDL_CreateWindow(window_title.c_str(),
197 SDL_WINDOWPOS_UNDEFINED, // x position
198 SDL_WINDOWPOS_UNDEFINED, // y position
199 Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height,
200 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
201
202 if (render_window == nullptr) {
203 LOG_CRITICAL(Frontend, "Failed to create SDL2 window! {}", SDL_GetError());
204 exit(1);
205 }
206
207 if (fullscreen) {
208 Fullscreen();
209 }
210 gl_context = SDL_GL_CreateContext(render_window);
211
212 if (gl_context == nullptr) {
213 LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! {}", SDL_GetError());
214 exit(1);
215 }
216
217 if (!gladLoadGLLoader(static_cast<GLADloadproc>(SDL_GL_GetProcAddress))) {
218 LOG_CRITICAL(Frontend, "Failed to initialize GL functions! {}", SDL_GetError());
219 exit(1);
220 }
221
222 if (!SupportsRequiredGLExtensions()) {
223 LOG_CRITICAL(Frontend, "GPU does not support all required OpenGL extensions! Exiting...");
224 exit(1);
225 }
226
227 OnResize();
228 OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size);
229 SDL_PumpEvents();
230 SDL_GL_SetSwapInterval(false);
231 LOG_INFO(Frontend, "yuzu Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
232 Common::g_scm_desc);
233 Settings::LogSettings();
234
235 DoneCurrent();
236}
237
238EmuWindow_SDL2::~EmuWindow_SDL2() {
239 InputCommon::Shutdown();
240 SDL_GL_DeleteContext(gl_context);
241 SDL_Quit();
242}
243
244void EmuWindow_SDL2::SwapBuffers() {
245 SDL_GL_SwapWindow(render_window);
246}
247
248void EmuWindow_SDL2::PollEvents() { 116void EmuWindow_SDL2::PollEvents() {
249 SDL_Event event; 117 SDL_Event event;
250 118
@@ -257,7 +125,11 @@ void EmuWindow_SDL2::PollEvents() {
257 case SDL_WINDOWEVENT_RESIZED: 125 case SDL_WINDOWEVENT_RESIZED:
258 case SDL_WINDOWEVENT_MAXIMIZED: 126 case SDL_WINDOWEVENT_MAXIMIZED:
259 case SDL_WINDOWEVENT_RESTORED: 127 case SDL_WINDOWEVENT_RESTORED:
128 OnResize();
129 break;
260 case SDL_WINDOWEVENT_MINIMIZED: 130 case SDL_WINDOWEVENT_MINIMIZED:
131 case SDL_WINDOWEVENT_EXPOSED:
132 is_shown = event.window.event == SDL_WINDOWEVENT_EXPOSED;
261 OnResize(); 133 OnResize();
262 break; 134 break;
263 case SDL_WINDOWEVENT_CLOSE: 135 case SDL_WINDOWEVENT_CLOSE:
@@ -300,20 +172,6 @@ void EmuWindow_SDL2::PollEvents() {
300 } 172 }
301} 173}
302 174
303void EmuWindow_SDL2::MakeCurrent() { 175void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) {
304 SDL_GL_MakeCurrent(render_window, gl_context);
305}
306
307void EmuWindow_SDL2::DoneCurrent() {
308 SDL_GL_MakeCurrent(render_window, nullptr);
309}
310
311void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(
312 const std::pair<unsigned, unsigned>& minimal_size) {
313
314 SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); 176 SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second);
315} 177}
316
317std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2::CreateSharedContext() const {
318 return std::make_unique<SDLGLContext>();
319}
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
index 17e98227f..d8051ebdf 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h
@@ -15,24 +15,13 @@ public:
15 explicit EmuWindow_SDL2(bool fullscreen); 15 explicit EmuWindow_SDL2(bool fullscreen);
16 ~EmuWindow_SDL2(); 16 ~EmuWindow_SDL2();
17 17
18 /// Swap buffers to display the next frame
19 void SwapBuffers() override;
20
21 /// Polls window events 18 /// Polls window events
22 void PollEvents() override; 19 void PollEvents() override;
23 20
24 /// Makes the graphics context current for the caller thread
25 void MakeCurrent() override;
26
27 /// Releases the GL context from the caller thread
28 void DoneCurrent() override;
29
30 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;
31
32 /// Whether the window is still open, and a close request hasn't yet been sent 21 /// Whether the window is still open, and a close request hasn't yet been sent
33 bool IsOpen() const; 22 bool IsOpen() const;
34 23
35private: 24protected:
36 /// Called by PollEvents when a key is pressed or released. 25 /// Called by PollEvents when a key is pressed or released.
37 void OnKeyEvent(int key, u8 state); 26 void OnKeyEvent(int key, u8 state);
38 27
@@ -60,20 +49,15 @@ private:
60 /// Called when user passes the fullscreen parameter flag 49 /// Called when user passes the fullscreen parameter flag
61 void Fullscreen(); 50 void Fullscreen();
62 51
63 /// Whether the GPU and driver supports the OpenGL extension required
64 bool SupportsRequiredGLExtensions();
65
66 /// Called when a configuration change affects the minimal size of the window 52 /// Called when a configuration change affects the minimal size of the window
67 void OnMinimalClientAreaChangeRequest( 53 void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) override;
68 const std::pair<unsigned, unsigned>& minimal_size) override;
69 54
70 /// Is the window still open? 55 /// Is the window still open?
71 bool is_open = true; 56 bool is_open = true;
72 57
58 /// Is the window being shown?
59 bool is_shown = true;
60
73 /// Internal SDL2 render window 61 /// Internal SDL2 render window
74 SDL_Window* render_window; 62 SDL_Window* render_window;
75
76 using SDL_GLContext = void*;
77 /// The OpenGL context associated with the window
78 SDL_GLContext gl_context;
79}; 63};
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
new file mode 100644
index 000000000..904022137
--- /dev/null
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp
@@ -0,0 +1,154 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <cstdlib>
7#include <string>
8#define SDL_MAIN_HANDLED
9#include <SDL.h>
10#include <fmt/format.h>
11#include <glad/glad.h>
12#include "common/logging/log.h"
13#include "common/scm_rev.h"
14#include "common/string_util.h"
15#include "core/settings.h"
16#include "input_common/keyboard.h"
17#include "input_common/main.h"
18#include "input_common/motion_emu.h"
19#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h"
20
21class SDLGLContext : public Core::Frontend::GraphicsContext {
22public:
23 explicit SDLGLContext() {
24 // create a hidden window to make the shared context against
25 window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, // x position
26 SDL_WINDOWPOS_UNDEFINED, // y position
27 Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height,
28 SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
29 context = SDL_GL_CreateContext(window);
30 }
31
32 ~SDLGLContext() {
33 SDL_GL_DeleteContext(context);
34 SDL_DestroyWindow(window);
35 }
36
37 void MakeCurrent() override {
38 SDL_GL_MakeCurrent(window, context);
39 }
40
41 void DoneCurrent() override {
42 SDL_GL_MakeCurrent(window, nullptr);
43 }
44
45 void SwapBuffers() override {}
46
47private:
48 SDL_Window* window;
49 SDL_GLContext context;
50};
51
52bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() {
53 std::vector<std::string> unsupported_ext;
54
55 if (!GLAD_GL_ARB_vertex_type_10f_11f_11f_rev)
56 unsupported_ext.push_back("ARB_vertex_type_10f_11f_11f_rev");
57 if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge)
58 unsupported_ext.push_back("ARB_texture_mirror_clamp_to_edge");
59 if (!GLAD_GL_ARB_multi_bind)
60 unsupported_ext.push_back("ARB_multi_bind");
61
62 // Extensions required to support some texture formats.
63 if (!GLAD_GL_EXT_texture_compression_s3tc)
64 unsupported_ext.push_back("EXT_texture_compression_s3tc");
65 if (!GLAD_GL_ARB_texture_compression_rgtc)
66 unsupported_ext.push_back("ARB_texture_compression_rgtc");
67 if (!GLAD_GL_ARB_depth_buffer_float)
68 unsupported_ext.push_back("ARB_depth_buffer_float");
69
70 for (const std::string& ext : unsupported_ext)
71 LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext);
72
73 return unsupported_ext.empty();
74}
75
76EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(bool fullscreen) : EmuWindow_SDL2(fullscreen) {
77 const SDL_GLprofile profile = Settings::values.use_compatibility_profile
78 ? SDL_GL_CONTEXT_PROFILE_COMPATIBILITY
79 : SDL_GL_CONTEXT_PROFILE_CORE;
80
81 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
82 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
83 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile);
84 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
85 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
86 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
87 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
88 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
89 SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
90
91 std::string window_title = fmt::format("yuzu {} | {}-{}", Common::g_build_fullname,
92 Common::g_scm_branch, Common::g_scm_desc);
93 render_window =
94 SDL_CreateWindow(window_title.c_str(),
95 SDL_WINDOWPOS_UNDEFINED, // x position
96 SDL_WINDOWPOS_UNDEFINED, // y position
97 Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height,
98 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
99
100 if (render_window == nullptr) {
101 LOG_CRITICAL(Frontend, "Failed to create SDL2 window! {}", SDL_GetError());
102 exit(1);
103 }
104
105 if (fullscreen) {
106 Fullscreen();
107 }
108 gl_context = SDL_GL_CreateContext(render_window);
109
110 if (gl_context == nullptr) {
111 LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! {}", SDL_GetError());
112 exit(1);
113 }
114
115 if (!gladLoadGLLoader(static_cast<GLADloadproc>(SDL_GL_GetProcAddress))) {
116 LOG_CRITICAL(Frontend, "Failed to initialize GL functions! {}", SDL_GetError());
117 exit(1);
118 }
119
120 if (!SupportsRequiredGLExtensions()) {
121 LOG_CRITICAL(Frontend, "GPU does not support all required OpenGL extensions! Exiting...");
122 exit(1);
123 }
124
125 OnResize();
126 OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size);
127 SDL_PumpEvents();
128 SDL_GL_SetSwapInterval(false);
129 LOG_INFO(Frontend, "yuzu Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
130 Common::g_scm_desc);
131 Settings::LogSettings();
132
133 DoneCurrent();
134}
135
136EmuWindow_SDL2_GL::~EmuWindow_SDL2_GL() {
137 SDL_GL_DeleteContext(gl_context);
138}
139
140void EmuWindow_SDL2_GL::SwapBuffers() {
141 SDL_GL_SwapWindow(render_window);
142}
143
144void EmuWindow_SDL2_GL::MakeCurrent() {
145 SDL_GL_MakeCurrent(render_window, gl_context);
146}
147
148void EmuWindow_SDL2_GL::DoneCurrent() {
149 SDL_GL_MakeCurrent(render_window, nullptr);
150}
151
152std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_GL::CreateSharedContext() const {
153 return std::make_unique<SDLGLContext>();
154}
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h
new file mode 100644
index 000000000..630deba93
--- /dev/null
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h
@@ -0,0 +1,34 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include "core/frontend/emu_window.h"
9#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
10
11class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 {
12public:
13 explicit EmuWindow_SDL2_GL(bool fullscreen);
14 ~EmuWindow_SDL2_GL();
15
16 /// Swap buffers to display the next frame
17 void SwapBuffers() override;
18
19 /// Makes the graphics context current for the caller thread
20 void MakeCurrent() override;
21
22 /// Releases the GL context from the caller thread
23 void DoneCurrent() override;
24
25 std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;
26
27private:
28 /// Whether the GPU and driver supports the OpenGL extension required
29 bool SupportsRequiredGLExtensions();
30
31 using SDL_GLContext = void*;
32 /// The OpenGL context associated with the window
33 SDL_GLContext gl_context;
34};
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index d3734927b..5d9442646 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -31,6 +31,7 @@
31#include "video_core/renderer_base.h" 31#include "video_core/renderer_base.h"
32#include "yuzu_cmd/config.h" 32#include "yuzu_cmd/config.h"
33#include "yuzu_cmd/emu_window/emu_window_sdl2.h" 33#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
34#include "yuzu_cmd/emu_window/emu_window_sdl2_gl.h"
34 35
35#include "core/file_sys/registered_cache.h" 36#include "core/file_sys/registered_cache.h"
36 37
@@ -173,7 +174,7 @@ int main(int argc, char** argv) {
173 Settings::values.use_gdbstub = use_gdbstub; 174 Settings::values.use_gdbstub = use_gdbstub;
174 Settings::Apply(); 175 Settings::Apply();
175 176
176 std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2>(fullscreen)}; 177 std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2_GL>(fullscreen)};
177 178
178 if (!Settings::values.use_multi_core) { 179 if (!Settings::values.use_multi_core) {
179 // Single core mode must acquire OpenGL context for entire emulation session 180 // Single core mode must acquire OpenGL context for entire emulation session