@ -9,6 +9,9 @@
# include <QKeyEvent>
# include <QMessageBox>
# include <QOffscreenSurface>
# include <QOpenGLContext>
# include <QOpenGLFunctions>
# include <QOpenGLFunctions_4_3_Core>
# include <QOpenGLWindow>
# include <QPainter>
# include <QScreen>
@ -23,9 +26,10 @@
# include "common/assert.h"
# include "common/microprofile.h"
# include "common/scm_rev.h"
# include "common/scope_exit.h"
# include "core/core.h"
# include "core/frontend/framebuffer_layout.h"
# include "core/frontend/scope_acquire_ window_ context.h"
# include "core/frontend/scope_acquire_ context.h"
# include "core/settings.h"
# include "input_common/keyboard.h"
# include "input_common/main.h"
@ -35,15 +39,27 @@
# include "yuzu/bootmanager.h"
# include "yuzu/main.h"
EmuThread : : EmuThread ( GRenderWindow * render_window ) : render_window ( render_window ) { }
EmuThread : : EmuThread ( GRenderWindow & window )
: shared_context { window . CreateSharedContext ( ) } ,
context { ( Settings : : values . use_asynchronous_gpu_emulation & & shared_context ) ? * shared_context
: window } { }
EmuThread : : ~ EmuThread ( ) = default ;
void EmuThread : : run ( ) {
render_window - > MakeCurrent ( ) ;
static GMainWindow * GetMainWindow ( ) {
for ( QWidget * w : qApp - > topLevelWidgets ( ) ) {
if ( GMainWindow * main = qobject_cast < GMainWindow * > ( w ) ) {
return main ;
}
}
return nullptr ;
}
void EmuThread : : run ( ) {
MicroProfileOnThreadCreate ( " EmuThread " ) ;
Core : : Frontend : : ScopeAcquireContext acquire_context { context } ;
emit LoadProgress ( VideoCore : : LoadCallbackStage : : Prepare , 0 , 0 ) ;
Core : : System : : GetInstance ( ) . Renderer ( ) . Rasterizer ( ) . LoadDiskResources (
@ -53,11 +69,6 @@ void EmuThread::run() {
emit LoadProgress ( VideoCore : : LoadCallbackStage : : Complete , 0 , 0 ) ;
if ( Settings : : values . use_asynchronous_gpu_emulation ) {
// Release OpenGL context for the GPU thread
render_window - > DoneCurrent ( ) ;
}
// Holds whether the cpu was running during the last iteration,
// so that the DebugModeLeft signal can be emitted before the
// next execution step
@ -98,190 +109,202 @@ void EmuThread::run() {
# if MICROPROFILE_ENABLED
MicroProfileOnThreadExit ( ) ;
# endif
render_window - > moveContext ( ) ;
}
class GGLContext : public Core : : Frontend : : GraphicsContext {
public :
explicit GGLContext ( QOpenGLContext * shared_context ) : shared_context { shared_context } {
context . setFormat ( shared_context - > format ( ) ) ;
context . setShareContext ( shared_context ) ;
context . create ( ) ;
explicit GGLContext ( QOpenGLContext * shared_context )
: context ( new QOpenGLContext ( shared_context - > parent ( ) ) ) ,
surface ( new QOffscreenSurface ( nullptr ) ) {
// disable vsync for any shared contexts
auto format = shared_context - > format ( ) ;
format . setSwapInterval ( 0 ) ;
context - > setShareContext ( shared_context ) ;
context - > setFormat ( format ) ;
context - > create ( ) ;
surface - > setParent ( shared_context - > parent ( ) ) ;
surface - > setFormat ( format ) ;
surface - > create ( ) ;
}
void MakeCurrent ( ) override {
context . makeCurrent ( shared_context - > surface ( ) ) ;
context - > makeCurrent ( surface ) ;
}
void DoneCurrent ( ) override {
context . doneCurrent ( ) ;
context - > doneCurrent ( ) ;
}
void SwapBuffers ( ) override { }
private :
QOpenGLContext * shared_ context;
QO penGLContext context ;
QOpenGLContext * context ;
QO ffscreenSurface* surface ;
} ;
class GWidgetInternal : public QWindow {
class ChildRenderWindow : public QWindow {
public :
GWidgetInternal( GRenderWindow * parent ) : parent ( parent ) { }
virtual ~ GWidgetInternal ( ) = default ;
ChildRenderWindow( QWindow * parent , QWidget * event_handler )
: QWindow { parent } , event_handler { event_handler } { }
void resizeEvent ( QResizeEvent * ev ) override {
parent - > OnClientAreaResized ( ev - > size ( ) . width ( ) , ev - > size ( ) . height ( ) ) ;
parent - > OnFramebufferSizeChanged ( ) ;
}
virtual ~ ChildRenderWindow ( ) = default ;
void keyPressEvent ( QKeyEvent * event ) override {
InputCommon : : GetKeyboard ( ) - > PressKey ( event - > key ( ) ) ;
}
virtual void Present ( ) = 0 ;
void keyReleaseEvent ( QKeyEvent * event ) override {
InputCommon : : GetKeyboard ( ) - > ReleaseKey ( event - > key ( ) ) ;
protected :
bool event ( QEvent * event ) override {
switch ( event - > type ( ) ) {
case QEvent : : UpdateRequest :
Present ( ) ;
return true ;
case QEvent : : MouseButtonPress :
case QEvent : : MouseButtonRelease :
case QEvent : : MouseButtonDblClick :
case QEvent : : MouseMove :
case QEvent : : KeyPress :
case QEvent : : KeyRelease :
case QEvent : : FocusIn :
case QEvent : : FocusOut :
case QEvent : : FocusAboutToChange :
case QEvent : : Enter :
case QEvent : : Leave :
case QEvent : : Wheel :
case QEvent : : TabletMove :
case QEvent : : TabletPress :
case QEvent : : TabletRelease :
case QEvent : : TabletEnterProximity :
case QEvent : : TabletLeaveProximity :
case QEvent : : TouchBegin :
case QEvent : : TouchUpdate :
case QEvent : : TouchEnd :
case QEvent : : InputMethodQuery :
case QEvent : : TouchCancel :
return QCoreApplication : : sendEvent ( event_handler , event ) ;
case QEvent : : Drop :
GetMainWindow ( ) - > DropAction ( static_cast < QDropEvent * > ( event ) ) ;
return true ;
case QEvent : : DragResponse :
case QEvent : : DragEnter :
case QEvent : : DragLeave :
case QEvent : : DragMove :
GetMainWindow ( ) - > AcceptDropEvent ( static_cast < QDropEvent * > ( event ) ) ;
return true ;
default :
return QWindow : : event ( event ) ;
}
}
void mousePressEvent ( QMouseEvent * event ) override {
if ( event - > source ( ) = = Qt : : MouseEventSynthesizedBySystem )
return ; // touch input is handled in TouchBeginEvent
const auto pos { event - > pos ( ) } ;
if ( event - > button ( ) = = Qt : : LeftButton ) {
const auto [ x , y ] = parent - > ScaleTouch ( pos ) ;
parent - > TouchPressed ( x , y ) ;
} else if ( event - > button ( ) = = Qt : : RightButton ) {
InputCommon : : GetMotionEmu ( ) - > BeginTilt ( pos . x ( ) , pos . y ( ) ) ;
}
void exposeEvent ( QExposeEvent * event ) override {
QWindow : : requestUpdate ( ) ;
QWindow : : exposeEvent ( event ) ;
}
void mouseMoveEvent ( QMouseEvent * event ) override {
if ( event - > source ( ) = = Qt : : MouseEventSynthesizedBySystem )
return ; // touch input is handled in TouchUpdateEvent
private :
QWidget * event_handler { } ;
} ;
const auto pos { event - > pos ( ) } ;
const auto [ x , y ] = parent - > ScaleTouch ( pos ) ;
parent - > TouchMoved ( x , y ) ;
InputCommon : : GetMotionEmu ( ) - > Tilt ( pos . x ( ) , pos . y ( ) ) ;
}
class OpenGLWindow final : public ChildRenderWindow {
public :
OpenGLWindow ( QWindow * parent , QWidget * event_handler , QOpenGLContext * shared_context )
: ChildRenderWindow { parent , event_handler } ,
context ( new QOpenGLContext ( shared_context - > parent ( ) ) ) {
void mouseReleaseEvent ( QMouseEvent * event ) override {
if ( event - > source ( ) = = Qt : : MouseEventSynthesizedBySystem )
return ; // touch input is handled in TouchEndEvent
// disable vsync for any shared contexts
auto format = shared_context - > format ( ) ;
format . setSwapInterval ( Settings : : values . use_vsync ? 1 : 0 ) ;
this - > setFormat ( format ) ;
if ( event - > button ( ) = = Qt : : LeftButton )
parent - > TouchReleased ( ) ;
else if ( event - > button ( ) = = Qt : : RightButton )
InputCommon : : GetMotionEmu ( ) - > EndTilt ( ) ;
}
context - > setShareContext ( shared_context ) ;
context - > setScreen ( this - > screen ( ) ) ;
context - > setFormat ( format ) ;
context - > create ( ) ;
void DisablePainting ( ) {
do_painting = false ;
}
setSurfaceType ( QWindow : : OpenGLSurface ) ;
void EnablePainting ( ) {
do_painting = true ;
// TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground,
// WA_DontShowOnScreen, WA_DeleteOnClose
}
std : : pair < unsigned , unsigned > GetSize ( ) const {
return std : : make_pair ( width ( ) , height ( ) ) ;
~ OpenGLWindow ( ) override {
context - > doneCurrent ( ) ;
}
protected :
bool IsPaintingEnabled ( ) const {
return do_painting ;
void Present ( ) override {
if ( ! isExposed ( ) ) {
return ;
}
context - > makeCurrent ( this ) ;
Core : : System : : GetInstance ( ) . Renderer ( ) . TryPresent ( 100 ) ;
context - > swapBuffers ( this ) ;
auto f = context - > versionFunctions < QOpenGLFunctions_4_3_Core > ( ) ;
f - > glFinish ( ) ;
QWindow : : requestUpdate ( ) ;
}
private :
GRenderWindow * parent ;
bool do_painting = false ;
} ;
// This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL
// context.
// The corresponding functionality is handled in EmuThread instead
class GGLWidgetInternal final : public GWidgetInternal , public QOpenGLWindow {
public :
GGLWidgetInternal ( GRenderWindow * parent , QOpenGLContext * shared_context )
: GWidgetInternal ( parent ) , QOpenGLWindow ( shared_context ) { }
~ GGLWidgetInternal ( ) override = default ;
void paintEvent ( QPaintEvent * ev ) override {
if ( IsPaintingEnabled ( ) ) {
QPainter painter ( this ) ;
}
}
QOpenGLContext * context { } ;
} ;
# ifdef HAS_VULKAN
class GVKWidgetInternal final : public GWidgetInternal {
class VulkanWindow final : public ChildRenderWindow {
public :
GVKWidgetInternal ( GRenderWindow * parent , QVulkanInstance * instance ) : GWidgetInternal ( parent ) {
VulkanWindow ( QWindow * parent , QWidget * event_handler , QVulkanInstance * instance )
: ChildRenderWindow { parent , event_handler } {
setSurfaceType ( QSurface : : SurfaceType : : VulkanSurface ) ;
setVulkanInstance ( instance ) ;
}
~ GVKWidgetInternal ( ) override = default ;
~ VulkanWindow ( ) override = default ;
void Present ( ) override {
// TODO(bunnei): ImplementMe
}
private :
QWidget * event_handler { } ;
} ;
# endif
GRenderWindow : : GRenderWindow ( GMainWindow * parent , EmuThread * emu_thread )
: QWidget ( parent ) , emu_thread ( emu_thread ) {
GRenderWindow : : GRenderWindow ( QWidget* parent_ , EmuThread * emu_thread )
: QWidget ( parent _ ) , emu_thread ( emu_thread ) {
setWindowTitle ( QStringLiteral ( " yuzu %1 | %2-%3 " )
. arg ( QString : : fromUtf8 ( Common : : g_build_name ) ,
QString : : fromUtf8 ( Common : : g_scm_branch ) ,
QString : : fromUtf8 ( Common : : g_scm_desc ) ) ) ;
setAttribute ( Qt : : WA_AcceptTouchEvents ) ;
auto layout = new QHBoxLayout ( this ) ;
layout - > setMargin ( 0 ) ;
setLayout ( layout ) ;
InputCommon : : Init ( ) ;
GMainWindow * parent = GetMainWindow ( ) ;
connect ( this , & GRenderWindow : : FirstFrameDisplayed , parent , & GMainWindow : : OnLoadComplete ) ;
}
GRenderWindow : : ~ GRenderWindow ( ) {
InputCommon : : Shutdown ( ) ;
// Avoid an unordered destruction that generates a segfault
delete child ;
}
void GRenderWindow : : moveContex t( ) {
if ( ! context) {
return ;
void GRenderWindow : : MakeCurrent ( ) {
if ( core_ context) {
core_context - > MakeCurrent ( ) ;
}
DoneCurrent ( ) ;
// If the thread started running, move the GL Context to the new thread. Otherwise, move it
// back.
auto thread = ( QThread : : currentThread ( ) = = qApp - > thread ( ) & & emu_thread ! = nullptr )
? emu_thread
: qApp - > thread ( ) ;
context - > moveToThread ( thread ) ;
}
void GRenderWindow : : SwapBuffers ( ) {
if ( co ntext) {
co ntext- > swapBuffers ( child ) ;
void GRenderWindow : : DoneCurrent ( ) {
if ( core_context ) {
core_context - > DoneCurrent ( ) ;
}
}
void GRenderWindow : : PollEvents ( ) {
if ( ! first_frame ) {
first_frame = true ;
emit FirstFrameDisplayed ( ) ;
}
}
void GRenderWindow : : MakeCurrent ( ) {
if ( context ) {
context - > makeCurrent ( child ) ;
}
}
void GRenderWindow : : DoneCurrent ( ) {
if ( context ) {
context - > doneCurrent ( ) ;
}
}
void GRenderWindow : : PollEvents ( ) { }
bool GRenderWindow : : IsShown ( ) const {
return ! isMinimized ( ) ;
}
@ -291,7 +314,7 @@ void GRenderWindow::RetrieveVulkanHandlers(void* get_instance_proc_addr, void* i
# ifdef HAS_VULKAN
const auto instance_proc_addr = vk_instance - > getInstanceProcAddr ( " vkGetInstanceProcAddr " ) ;
const VkInstance instance_copy = vk_instance - > vkInstance ( ) ;
const VkSurfaceKHR surface_copy = vk_instance - > surfaceForWindow ( child ) ;
const VkSurfaceKHR surface_copy = vk_instance - > surfaceForWindow ( child _window ) ;
std : : memcpy ( get_instance_proc_addr , & instance_proc_addr , sizeof ( instance_proc_addr ) ) ;
std : : memcpy ( instance , & instance_copy , sizeof ( instance_copy ) ) ;
@ -309,21 +332,10 @@ void GRenderWindow::RetrieveVulkanHandlers(void* get_instance_proc_addr, void* i
void GRenderWindow : : OnFramebufferSizeChanged ( ) {
// Screen changes potentially incur a change in screen DPI, hence we should update the
// framebuffer size
const qreal pixelRatio { GetWindowPixelRatio ( ) } ;
const auto size { child - > GetSize ( ) } ;
UpdateCurrentFramebufferLayout ( size . first * pixelRatio , size . second * pixelRatio ) ;
}
void GRenderWindow : : ForwardKeyPressEvent ( QKeyEvent * event ) {
if ( child ) {
child - > keyPressEvent ( event ) ;
}
}
void GRenderWindow : : ForwardKeyReleaseEvent ( QKeyEvent * event ) {
if ( child ) {
child - > keyReleaseEvent ( event ) ;
}
const qreal pixel_ratio = windowPixelRatio ( ) ;
const u32 width = this - > width ( ) * pixel_ratio ;
const u32 height = this - > height ( ) * pixel_ratio ;
UpdateCurrentFramebufferLayout ( width , height ) ;
}
void GRenderWindow : : BackupGeometry ( ) {
@ -351,13 +363,12 @@ QByteArray GRenderWindow::saveGeometry() {
return geometry ;
}
qreal GRenderWindow : : GetWindowPixelRatio ( ) const {
// windowHandle() might not be accessible until the window is displayed to screen.
return windowHandle ( ) ? windowHandle ( ) - > screen ( ) - > devicePixelRatio ( ) : 1.0f ;
qreal GRenderWindow : : windowPixelRatio ( ) const {
return devicePixelRatio ( ) ;
}
std : : pair < u32 , u32 > GRenderWindow : : ScaleTouch ( const QPointF pos ) const {
const qreal pixel_ratio { GetWindowPixelRatio ( ) } ;
const qreal pixel_ratio = windowPixelRatio ( ) ;
return { static_cast < u32 > ( std : : max ( std : : round ( pos . x ( ) * pixel_ratio ) , qreal { 0.0 } ) ) ,
static_cast < u32 > ( std : : max ( std : : round ( pos . y ( ) * pixel_ratio ) , qreal { 0.0 } ) ) } ;
}
@ -367,6 +378,47 @@ void GRenderWindow::closeEvent(QCloseEvent* event) {
QWidget : : closeEvent ( event ) ;
}
void GRenderWindow : : keyPressEvent ( QKeyEvent * event ) {
InputCommon : : GetKeyboard ( ) - > PressKey ( event - > key ( ) ) ;
}
void GRenderWindow : : keyReleaseEvent ( QKeyEvent * event ) {
InputCommon : : GetKeyboard ( ) - > ReleaseKey ( event - > key ( ) ) ;
}
void GRenderWindow : : mousePressEvent ( QMouseEvent * event ) {
if ( event - > source ( ) = = Qt : : MouseEventSynthesizedBySystem )
return ; // touch input is handled in TouchBeginEvent
auto pos = event - > pos ( ) ;
if ( event - > button ( ) = = Qt : : LeftButton ) {
const auto [ x , y ] = ScaleTouch ( pos ) ;
this - > TouchPressed ( x , y ) ;
} else if ( event - > button ( ) = = Qt : : RightButton ) {
InputCommon : : GetMotionEmu ( ) - > BeginTilt ( pos . x ( ) , pos . y ( ) ) ;
}
}
void GRenderWindow : : mouseMoveEvent ( QMouseEvent * event ) {
if ( event - > source ( ) = = Qt : : MouseEventSynthesizedBySystem )
return ; // touch input is handled in TouchUpdateEvent
auto pos = event - > pos ( ) ;
const auto [ x , y ] = ScaleTouch ( pos ) ;
this - > TouchMoved ( x , y ) ;
InputCommon : : GetMotionEmu ( ) - > Tilt ( pos . x ( ) , pos . y ( ) ) ;
}
void GRenderWindow : : mouseReleaseEvent ( QMouseEvent * event ) {
if ( event - > source ( ) = = Qt : : MouseEventSynthesizedBySystem )
return ; // touch input is handled in TouchEndEvent
if ( event - > button ( ) = = Qt : : LeftButton )
this - > TouchReleased ( ) ;
else if ( event - > button ( ) = = Qt : : RightButton )
InputCommon : : GetMotionEmu ( ) - > EndTilt ( ) ;
}
void GRenderWindow : : TouchBeginEvent ( const QTouchEvent * event ) {
// TouchBegin always has exactly one touch point, so take the .first()
const auto [ x , y ] = ScaleTouch ( event - > touchPoints ( ) . first ( ) . pos ( ) ) ;
@ -415,26 +467,20 @@ void GRenderWindow::focusOutEvent(QFocusEvent* event) {
InputCommon : : GetKeyboard ( ) - > ReleaseAllKeys ( ) ;
}
void GRenderWindow : : OnClientAreaResized ( u32 width , u32 height ) {
NotifyClientAreaSizeChanged ( std : : make_pair ( width , height ) ) ;
void GRenderWindow : : resizeEvent ( QResizeEvent * event ) {
QWidget : : resizeEvent ( event ) ;
OnFramebufferSizeChanged ( ) ;
}
std : : unique_ptr < Core : : Frontend : : GraphicsContext > GRenderWindow : : CreateSharedContext ( ) const {
return std : : make_unique < GGLContext > ( context . get ( ) ) ;
if ( Settings : : values . renderer_backend = = Settings : : RendererBackend : : OpenGL ) {
return std : : make_unique < GGLContext > ( QOpenGLContext : : globalShareContext ( ) ) ;
}
return { } ;
}
bool GRenderWindow : : InitRenderTarget ( ) {
shared_context . reset ( ) ;
context . reset ( ) ;
if ( child ) {
delete child ;
}
if ( container ) {
delete container ;
}
if ( layout ( ) ) {
delete layout ( ) ;
}
ReleaseRenderTarget ( ) ;
first_frame = false ;
@ -451,13 +497,6 @@ bool GRenderWindow::InitRenderTarget() {
break ;
}
container = QWidget : : createWindowContainer ( child , this ) ;
QBoxLayout * layout = new QHBoxLayout ( this ) ;
layout - > addWidget ( container ) ;
layout - > setMargin ( 0 ) ;
setLayout ( layout ) ;
// Reset minimum required size to avoid resizing issues on the main window after restarting.
setMinimumSize ( 1 , 1 ) ;
@ -467,14 +506,9 @@ bool GRenderWindow::InitRenderTarget() {
hide ( ) ;
resize ( Layout : : ScreenUndocked : : Width , Layout : : ScreenUndocked : : Height ) ;
child - > resize ( Layout : : ScreenUndocked : : Width , Layout : : ScreenUndocked : : Height ) ;
container - > resize ( Layout : : ScreenUndocked : : Width , Layout : : ScreenUndocked : : Height ) ;
OnMinimalClientAreaChangeRequest ( GetActiveConfig ( ) . min_client_area_size ) ;
OnFramebufferSizeChanged ( ) ;
NotifyClientAreaSizeChanged ( child - > GetSize ( ) ) ;
BackupGeometry ( ) ;
if ( Settings : : values . renderer_backend = = Settings : : RendererBackend : : OpenGL ) {
@ -486,6 +520,14 @@ bool GRenderWindow::InitRenderTarget() {
return true ;
}
void GRenderWindow : : ReleaseRenderTarget ( ) {
if ( child_widget ) {
layout ( ) - > removeWidget ( child_widget ) ;
delete child_widget ;
child_widget = nullptr ;
}
}
void GRenderWindow : : CaptureScreenshot ( u32 res_scale , const QString & screenshot_path ) {
auto & renderer = Core : : System : : GetInstance ( ) . Renderer ( ) ;
@ -521,16 +563,19 @@ bool GRenderWindow::InitializeOpenGL() {
fmt . setOption ( QSurfaceFormat : : FormatOption : : DeprecatedFunctions ) ;
// TODO: expose a setting for buffer value (ie default/single/double/triple)
fmt . setSwapBehavior ( QSurfaceFormat : : DefaultSwapBehavior ) ;
shared_context = std : : make_unique < QOpenGLContext > ( ) ;
shared_context - > setFormat ( fmt ) ;
shared_context - > create ( ) ;
context = std : : make_unique < QOpenGLContext > ( ) ;
context - > setShareContext ( shared_context . get ( ) ) ;
context - > setFormat ( fmt ) ;
context - > create ( ) ;
fmt . setSwapInterval ( false ) ;
child = new GGLWidgetInternal ( this , shared_context . get ( ) ) ;
fmt . setSwapInterval ( 0 ) ;
QSurfaceFormat : : setDefaultFormat ( fmt ) ;
GMainWindow * parent = GetMainWindow ( ) ;
QWindow * parent_win_handle = parent ? parent - > windowHandle ( ) : nullptr ;
child_window = new OpenGLWindow ( parent_win_handle , this , QOpenGLContext : : globalShareContext ( ) ) ;
child_window - > create ( ) ;
child_widget = createWindowContainer ( child_window , this ) ;
child_widget - > resize ( Layout : : ScreenUndocked : : Width , Layout : : ScreenUndocked : : Height ) ;
layout ( ) - > addWidget ( child_widget ) ;
core_context = CreateSharedContext ( ) ;
return true ;
}
@ -559,7 +604,14 @@ bool GRenderWindow::InitializeVulkan() {
return false ;
}
child = new GVKWidgetInternal ( this , vk_instance . get ( ) ) ;
GMainWindow * parent = GetMainWindow ( ) ;
QWindow * parent_win_handle = parent ? parent - > windowHandle ( ) : nullptr ;
child_window = new VulkanWindow ( parent_win_handle , this , vk_instance . get ( ) ) ;
child_window - > create ( ) ;
child_widget = createWindowContainer ( child_window , this ) ;
child_widget - > resize ( Layout : : ScreenUndocked : : Width , Layout : : ScreenUndocked : : Height ) ;
layout ( ) - > addWidget ( child_widget ) ;
return true ;
# else
QMessageBox : : critical ( this , tr ( " Vulkan not available! " ) ,
@ -569,7 +621,7 @@ bool GRenderWindow::InitializeVulkan() {
}
bool GRenderWindow : : LoadOpenGL ( ) {
Core : : Frontend : : ScopeAcquire Window Context acquire_context { * this } ;
Core : : Frontend : : ScopeAcquire Context acquire_context { * this } ;
if ( ! gladLoadGL ( ) ) {
QMessageBox : : critical ( this , tr ( " Error while initializing OpenGL 4.3! " ) ,
tr ( " Your GPU may not support OpenGL 4.3, or you do not have the "
@ -621,12 +673,10 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const {
void GRenderWindow : : OnEmulationStarting ( EmuThread * emu_thread ) {
this - > emu_thread = emu_thread ;
child - > DisablePainting ( ) ;
}
void GRenderWindow : : OnEmulationStopping ( ) {
emu_thread = nullptr ;
child - > EnablePainting ( ) ;
}
void GRenderWindow : : showEvent ( QShowEvent * event ) {