Skip to content

Commit

Permalink
feat: 支持检测运行时显卡变化
Browse files Browse the repository at this point in the history
  • Loading branch information
Blinue committed Dec 23, 2024
1 parent cc4c03d commit fe7bffa
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 78 deletions.
1 change: 1 addition & 0 deletions src/Magpie.Core/DeviceResources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ bool DeviceResources::_ObtainAdapterAndDevice(GraphicsCardId graphicsCardId) noe
}

// 枚举查找 vendorId 和 deviceId 匹配的显卡
assert(graphicsCardId.vendorId != 0 && graphicsCardId.deviceId != 0);
UINT adapterIndex = graphicsCardId.idx == 0 ? 1 : 0;
while (SUCCEEDED(_dxgiFactory->EnumAdapters1(adapterIndex, adapter.put()))) {
DXGI_ADAPTER_DESC1 desc;
Expand Down
72 changes: 72 additions & 0 deletions src/Magpie/AdaptersService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ bool AdaptersService::Initialize() noexcept {
});
}

_UpdateProfiles();

_monitorThread = std::thread(std::bind_front(&AdaptersService::_MonitorThreadProc, this));
return true;
}
Expand Down Expand Up @@ -127,6 +129,7 @@ bool AdaptersService::_GatherAdapterInfos(

App::Get().Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, adapterInfos(std::move(adapterInfos))]() {
_adapterInfos = std::move(adapterInfos);
_UpdateProfiles();
AdaptersChanged.Invoke();
});

Expand Down Expand Up @@ -182,4 +185,73 @@ void AdaptersService::_MonitorThreadProc() noexcept {
dxgiFactory->UnregisterAdaptersChangedEvent(adaptersChangedCookie);
}

// 有更改返回 true
bool AdaptersService::_UpdateProfileGraphicsCardId(Profile& profile, int adapterCount) noexcept {
GraphicsCardId& gcid = profile.graphicsCardId;

if (gcid.vendorId == 0 && gcid.deviceId == 0) {
if (gcid.idx < 0) {
// 使用默认显卡
return false;
}

// 来自旧版本的配置文件不存在 vendorId 和 deviceId,更新为新版本
if (gcid.idx < adapterCount) {
const AdapterInfo& ai = _adapterInfos[gcid.idx];
gcid.vendorId = ai.vendorId;
gcid.deviceId = ai.deviceId;
} else {
// 非法序号改为使用默认显卡,无论如何原始配置已经丢失
gcid.idx = -1;
}

return true;
}

if (gcid.idx >= 0 && gcid.idx < adapterCount) {
const AdapterInfo& ai = _adapterInfos[gcid.idx];
if (ai.vendorId == gcid.vendorId && ai.deviceId == gcid.deviceId) {
// 全部匹配
return false;
}
}

// 序号指定的显卡不匹配则查找新序号。找不到时将 idx 置为 -1 表示使用默认显卡,
// 不改变 vendorId 和 deviceId,这样当指定的显卡再次可用时将自动使用。
gcid.idx = -1;
for (int i = 0; i < adapterCount; ++i) {
if (i == gcid.idx) {
continue;
}

const AdapterInfo& ai = _adapterInfos[i];
if (ai.vendorId == gcid.vendorId && ai.deviceId == gcid.deviceId) {
gcid.idx = i;
break;
}
}

return true;
}

void AdaptersService::_UpdateProfiles() noexcept {
bool needSave = false;
const int adapterInfoCount = (int)_adapterInfos.size();

// 更新所有配置文件的显卡配置
if (_UpdateProfileGraphicsCardId(AppSettings::Get().DefaultProfile(), adapterInfoCount)) {
needSave = true;
}

for (Profile& profile : AppSettings::Get().Profiles()) {
if (_UpdateProfileGraphicsCardId(profile, adapterInfoCount)) {
needSave = true;
}
}

if (needSave) {
AppSettings::Get().SaveAsync();
}
}

}
6 changes: 6 additions & 0 deletions src/Magpie/AdaptersService.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace Magpie {

struct Profile;

struct AdapterInfo {
uint32_t idx = 0;
uint32_t vendorId = 0;
Expand Down Expand Up @@ -45,6 +47,10 @@ class AdaptersService {

void _MonitorThreadProc() noexcept;

bool _UpdateProfileGraphicsCardId(Profile& profile, int adapterCount) noexcept;

void _UpdateProfiles() noexcept;

std::thread _monitorThread;
std::vector<AdapterInfo> _adapterInfos;
};
Expand Down
2 changes: 0 additions & 2 deletions src/Magpie/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#include "TextBlockHelper.h"
#include "MainWindow.h"
#include "AdaptersService.h"
#include "ProfileService.h"

using namespace ::Magpie;
using namespace winrt;
Expand Down Expand Up @@ -171,7 +170,6 @@ bool App::Initialize(const wchar_t* arguments) {
_Uninitialize();
return false;
}
ProfileService::Get().Initialize();
ShortcutService::Get().Initialize();
ScalingService::Get().Initialize();
UpdateService::Get().Initialize();
Expand Down
4 changes: 2 additions & 2 deletions src/Magpie/ProfilePage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,13 @@
<local:SettingsGroup x:Uid="Profile_Performance">
<local:SettingsCard x:Name="GraphicsCardSettingsCard"
x:Uid="Profile_Performance_GraphicsCard"
x:Load="{x:Bind ViewModel.IsShowGraphicsCardSettingsCard, Mode=OneTime}"
x:Load="{x:Bind ViewModel.IsShowGraphicsCardSettingsCard, Mode=OneWay}"
IsWrapEnabled="True">
<local:SettingsCard.HeaderIcon>
<FontIcon Glyph="&#xf211;" />
</local:SettingsCard.HeaderIcon>
<ComboBox DropDownOpened="ComboBox_DropDownOpened"
ItemsSource="{x:Bind ViewModel.GraphicsCards, Mode=OneTime}"
ItemsSource="{x:Bind ViewModel.GraphicsCards, Mode=OneWay}"
SelectedIndex="{x:Bind ViewModel.GraphicsCard, Mode=TwoWay}" />
</local:SettingsCard>
<local:SettingsCard x:Uid="Profile_Performance_ShowFPS">
Expand Down
71 changes: 0 additions & 71 deletions src/Magpie/ProfileService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,77 +123,6 @@ static bool TestNewProfileImpl(
return true;
}

// 由更改返回 true
static bool UpdateProfileGraphicsCardId(Profile& profile) noexcept {
const std::vector<AdapterInfo>& adapterInfos = AdaptersService::Get().AdapterInfos();
const int adapterInfoCount = (int)adapterInfos.size();

GraphicsCardId& gcid = profile.graphicsCardId;

if (gcid.vendorId == 0 && gcid.deviceId == 0) {
if (gcid.idx < 0) {
// 使用默认显卡
return false;
}

// 来自旧版本的配置文件不存在 vendorId 和 deviceId,更新为新版本
if (gcid.idx < adapterInfoCount) {
const AdapterInfo& ai = adapterInfos[gcid.idx];
gcid.vendorId = ai.vendorId;
gcid.deviceId = ai.deviceId;
} else {
// 非法序号改为使用默认显卡,无论如何原始配置已经丢失
gcid.idx = -1;
}

return true;
}

if (gcid.idx >= 0 && gcid.idx < adapterInfoCount) {
const AdapterInfo& ai = adapterInfos[gcid.idx];
if (ai.vendorId == gcid.vendorId && ai.deviceId == gcid.deviceId) {
// 全部匹配
return false;
}
}

// 序号指定的显卡不匹配则查找新序号。找不到时将 idx 置为 -1 表示使用默认显卡,
// 不改变 vendorId 和 deviceId,这样当指定的显卡再次可用时将自动使用。
gcid.idx = -1;
for (int i = 0; i < adapterInfoCount; ++i) {
if (i == gcid.idx) {
continue;
}

const AdapterInfo& ai = adapterInfos[i];
if (ai.vendorId == gcid.vendorId && ai.deviceId == gcid.deviceId) {
gcid.idx = i;
break;
}
}

return true;
}

void ProfileService::Initialize() noexcept {
bool needSave = false;

// 更新所有配置文件的显卡配置
if (UpdateProfileGraphicsCardId(AppSettings::Get().DefaultProfile())) {
needSave = true;
}

for (Profile& profile : AppSettings::Get().Profiles()) {
if (UpdateProfileGraphicsCardId(profile)) {
needSave = true;
}
}

if (needSave) {
AppSettings::Get().SaveAsync();
}
}

bool ProfileService::TestNewProfile(bool isPackaged, std::wstring_view pathOrAumid, std::wstring_view className) noexcept {
if (pathOrAumid.empty() || className.empty()) {
return false;
Expand Down
2 changes: 0 additions & 2 deletions src/Magpie/ProfileService.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ class ProfileService {
ProfileService(const ProfileService&) = delete;
ProfileService(ProfileService&&) = delete;

void Initialize() noexcept;

bool TestNewProfile(bool isPackaged, std::wstring_view pathOrAumid, std::wstring_view className) noexcept;

// copyFrom < 0 表示复制默认配置
Expand Down
13 changes: 12 additions & 1 deletion src/Magpie/ProfileViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ ProfileViewModel::ProfileViewModel(int profileIdx) : _isDefaultProfile(profileId

_captureMethods = single_threaded_vector(std::move(captureMethods));
}

_adaptersChangedRevoker = AdaptersService::Get().AdaptersChanged(auto_revoke,
std::bind_front(&ProfileViewModel::_AdaptersService_AdaptersChanged, this));
}

ProfileViewModel::~ProfileViewModel() {}
Expand Down Expand Up @@ -428,7 +431,7 @@ int ProfileViewModel::GraphicsCard() const noexcept {
}

void ProfileViewModel::GraphicsCard(int value) {
if (value < 0) {
if (value < 0 || _isHandlingAdapterChanged) {
return;
}

Expand Down Expand Up @@ -793,4 +796,12 @@ fire_and_forget ProfileViewModel::_LoadIcon() {
RaisePropertyChanged(L"Icon");
}

void ProfileViewModel::_AdaptersService_AdaptersChanged() {
_isHandlingAdapterChanged = true;
RaisePropertyChanged(L"IsShowGraphicsCardSettingsCard");
RaisePropertyChanged(L"GraphicsCards");
RaisePropertyChanged(L"GraphicsCard");
_isHandlingAdapterChanged = false;
}

}
4 changes: 4 additions & 0 deletions src/Magpie/ProfileViewModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ struct ProfileViewModel : ProfileViewModelT<ProfileViewModel>,
private:
fire_and_forget _LoadIcon();

void _AdaptersService_AdaptersChanged();

bool _isProgramExist = true;

hstring _renameText;
Expand All @@ -158,11 +160,13 @@ struct ProfileViewModel : ProfileViewModelT<ProfileViewModel>,

::Magpie::MultithreadEvent<bool>::EventRevoker _appThemeChangedRevoker;
::Magpie::Event<uint32_t>::EventRevoker _dpiChangedRevoker;
::Magpie::Event<>::EventRevoker _adaptersChangedRevoker;

Controls::IconElement _icon{ nullptr };

const bool _isDefaultProfile = true;
bool _isRenameConfirmButtonEnabled = false;
bool _isHandlingAdapterChanged = false;
};

}

0 comments on commit fe7bffa

Please sign in to comment.