mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-06 23:19:57 +01:00
macos: Patch QMetalLayer.setNeedsDisplayInRect at runtime to avoid freezing on recent Qt
This commit is contained in:
parent
bf03cac9e1
commit
16b8a78571
@ -60,6 +60,10 @@ if (ENABLE_QT AND UNIX AND NOT APPLE)
|
|||||||
target_link_libraries(citra_meta PRIVATE Qt6::DBus gamemode)
|
target_link_libraries(citra_meta PRIVATE Qt6::DBus gamemode)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_QT AND APPLE)
|
||||||
|
target_link_libraries(citra_meta PRIVATE Qt6::GuiPrivate)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (ENABLE_QT AND USE_DISCORD_PRESENCE)
|
if (ENABLE_QT AND USE_DISCORD_PRESENCE)
|
||||||
target_link_libraries(citra_meta PRIVATE discord-rpc)
|
target_link_libraries(citra_meta PRIVATE discord-rpc)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -172,12 +172,12 @@ add_library(citra_qt STATIC EXCLUDE_FROM_ALL
|
|||||||
multiplayer/state.h
|
multiplayer/state.h
|
||||||
multiplayer/validation.h
|
multiplayer/validation.h
|
||||||
precompiled_headers.h
|
precompiled_headers.h
|
||||||
|
qt_image_interface.cpp
|
||||||
|
qt_image_interface.h
|
||||||
uisettings.cpp
|
uisettings.cpp
|
||||||
uisettings.h
|
uisettings.h
|
||||||
user_data_migration.cpp
|
user_data_migration.cpp
|
||||||
user_data_migration.h
|
user_data_migration.h
|
||||||
qt_image_interface.cpp
|
|
||||||
qt_image_interface.h
|
|
||||||
util/clickable_label.cpp
|
util/clickable_label.cpp
|
||||||
util/clickable_label.h
|
util/clickable_label.h
|
||||||
util/graphics_device_info.cpp
|
util/graphics_device_info.cpp
|
||||||
@ -190,6 +190,13 @@ add_library(citra_qt STATIC EXCLUDE_FROM_ALL
|
|||||||
util/util.h
|
util/util.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
target_sources(citra_qt PUBLIC
|
||||||
|
qt_swizzle.h
|
||||||
|
qt_swizzle.mm
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
file(GLOB COMPAT_LIST
|
file(GLOB COMPAT_LIST
|
||||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
||||||
@ -275,6 +282,10 @@ if (NOT WIN32)
|
|||||||
target_include_directories(citra_qt PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
target_include_directories(citra_qt PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
target_link_libraries(citra_qt PRIVATE Qt6::GuiPrivate)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
target_link_libraries(citra_qt PRIVATE Qt6::DBus gamemode)
|
target_link_libraries(citra_qt PRIVATE Qt6::DBus gamemode)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -69,6 +69,7 @@
|
|||||||
#include "citra_qt/movie/movie_record_dialog.h"
|
#include "citra_qt/movie/movie_record_dialog.h"
|
||||||
#include "citra_qt/multiplayer/state.h"
|
#include "citra_qt/multiplayer/state.h"
|
||||||
#include "citra_qt/qt_image_interface.h"
|
#include "citra_qt/qt_image_interface.h"
|
||||||
|
#include "citra_qt/qt_swizzle.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/play_time_manager.h"
|
#include "common/play_time_manager.h"
|
||||||
#ifdef ENABLE_QT_UPDATE_CHECKER
|
#ifdef ENABLE_QT_UPDATE_CHECKER
|
||||||
@ -4112,6 +4113,11 @@ static Qt::HighDpiScaleFactorRoundingPolicy GetHighDpiRoundingPolicy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LaunchQtFrontend(int argc, char* argv[]) {
|
void LaunchQtFrontend(int argc, char* argv[]) {
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// Ensure that the linker doesn't optimize qt_swizzle.mm out of existence.
|
||||||
|
QtSwizzle::Dummy();
|
||||||
|
#endif
|
||||||
|
|
||||||
Common::DetachedTasks detached_tasks;
|
Common::DetachedTasks detached_tasks;
|
||||||
|
|
||||||
#if MICROPROFILE_ENABLED
|
#if MICROPROFILE_ENABLED
|
||||||
|
|||||||
9
src/citra_qt/qt_swizzle.h
Normal file
9
src/citra_qt/qt_swizzle.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
namespace QtSwizzle {
|
||||||
|
|
||||||
|
void Dummy();
|
||||||
|
|
||||||
|
} // namespace QtSwizzle
|
||||||
48
src/citra_qt/qt_swizzle.mm
Normal file
48
src/citra_qt/qt_swizzle.mm
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#import <QtGui/private/qmetallayer_p.h>
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
|
namespace QtSwizzle {
|
||||||
|
|
||||||
|
void Dummy() {
|
||||||
|
// Call this anywhere to make sure that qt_swizzle.mm is linked.
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QtSwizzle
|
||||||
|
|
||||||
|
@implementation QMetalLayer (AzaharPatch)
|
||||||
|
|
||||||
|
+ (void)load {
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
Class targetClass = [self class];
|
||||||
|
|
||||||
|
// Get the original and swizzled methods
|
||||||
|
Method originalMethod =
|
||||||
|
class_getInstanceMethod(targetClass, @selector(setNeedsDisplayInRect:));
|
||||||
|
Method swizzledMethod =
|
||||||
|
class_getInstanceMethod(targetClass, @selector(swizzled_setNeedsDisplayInRect:));
|
||||||
|
|
||||||
|
// Swap the implementations
|
||||||
|
method_exchangeImplementations(originalMethod, swizzledMethod);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)swizzled_setNeedsDisplayInRect:(CGRect)rect {
|
||||||
|
constexpr auto tooBig = 1e10; // Arbitrary large number
|
||||||
|
|
||||||
|
// Check for problematic huge rectangles
|
||||||
|
if ((!self.needsDisplay) && (rect.size.width > tooBig || rect.size.height > tooBig ||
|
||||||
|
rect.origin.x < -tooBig || rect.origin.y < -tooBig)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the original implementation
|
||||||
|
[self swizzled_setNeedsDisplayInRect:rect];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
Loading…
x
Reference in New Issue
Block a user