HostDisplay: Implement exclusive fullscreen for D3D11 renderer
This commit is contained in:
@@ -42,10 +42,12 @@ DisplaySettingsWidget::DisplaySettingsWidget(QtHostInterface* host_interface, QW
|
||||
false);
|
||||
|
||||
connect(m_ui.renderer, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DisplaySettingsWidget::populateGPUAdapters);
|
||||
&DisplaySettingsWidget::populateGPUAdaptersAndResolutions);
|
||||
connect(m_ui.adapter, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DisplaySettingsWidget::onGPUAdapterIndexChanged);
|
||||
populateGPUAdapters();
|
||||
connect(m_ui.fullscreenMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&DisplaySettingsWidget::onGPUFullscreenModeIndexChanged);
|
||||
populateGPUAdaptersAndResolutions();
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.renderer, tr("Renderer"),
|
||||
@@ -118,15 +120,20 @@ void DisplaySettingsWidget::setupAdditionalUi()
|
||||
}
|
||||
}
|
||||
|
||||
void DisplaySettingsWidget::populateGPUAdapters()
|
||||
void DisplaySettingsWidget::populateGPUAdaptersAndResolutions()
|
||||
{
|
||||
std::vector<std::string> adapter_names;
|
||||
std::vector<std::string> fullscreen_modes;
|
||||
switch (static_cast<GPURenderer>(m_ui.renderer->currentIndex()))
|
||||
{
|
||||
#ifdef WIN32
|
||||
case GPURenderer::HardwareD3D11:
|
||||
adapter_names = FrontendCommon::D3D11HostDisplay::EnumerateAdapterNames();
|
||||
break;
|
||||
{
|
||||
FrontendCommon::D3D11HostDisplay::AdapterInfo adapter_info = FrontendCommon::D3D11HostDisplay::GetAdapterInfo();
|
||||
adapter_names = std::move(adapter_info.adapter_names);
|
||||
fullscreen_modes = std::move(adapter_info.fullscreen_modes);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GPURenderer::HardwareVulkan:
|
||||
@@ -137,26 +144,46 @@ void DisplaySettingsWidget::populateGPUAdapters()
|
||||
break;
|
||||
}
|
||||
|
||||
QString current_value = QString::fromStdString(m_host_interface->GetStringSettingValue("GPU", "Adapter"));
|
||||
|
||||
QSignalBlocker blocker(m_ui.adapter);
|
||||
|
||||
// add the default entry - we'll fall back to this if the GPU no longer exists, or there's no options
|
||||
m_ui.adapter->clear();
|
||||
m_ui.adapter->addItem(tr("(Default)"));
|
||||
|
||||
// add the other adapters
|
||||
for (const std::string& adapter_name : adapter_names)
|
||||
{
|
||||
QString qadapter_name(QString::fromStdString(adapter_name));
|
||||
m_ui.adapter->addItem(qadapter_name);
|
||||
const std::string current_adapter(m_host_interface->GetStringSettingValue("GPU", "Adapter"));
|
||||
QSignalBlocker blocker(m_ui.adapter);
|
||||
|
||||
if (qadapter_name == current_value)
|
||||
m_ui.adapter->setCurrentIndex(m_ui.adapter->count() - 1);
|
||||
// add the default entry - we'll fall back to this if the GPU no longer exists, or there's no options
|
||||
m_ui.adapter->clear();
|
||||
m_ui.adapter->addItem(tr("(Default)"));
|
||||
|
||||
// add the other adapters
|
||||
for (const std::string& adapter_name : adapter_names)
|
||||
{
|
||||
m_ui.adapter->addItem(QString::fromStdString(adapter_name));
|
||||
|
||||
if (adapter_name == current_adapter)
|
||||
m_ui.adapter->setCurrentIndex(m_ui.adapter->count() - 1);
|
||||
}
|
||||
|
||||
// disable it if we don't have a choice
|
||||
m_ui.adapter->setEnabled(!adapter_names.empty());
|
||||
}
|
||||
|
||||
// disable it if we don't have a choice
|
||||
m_ui.adapter->setEnabled(!adapter_names.empty());
|
||||
{
|
||||
const std::string current_mode(m_host_interface->GetStringSettingValue("GPU", "FullscreenMode", ""));
|
||||
QSignalBlocker blocker(m_ui.fullscreenMode);
|
||||
|
||||
m_ui.fullscreenMode->clear();
|
||||
m_ui.fullscreenMode->addItem(tr("Borderless Fullscreen"));
|
||||
m_ui.fullscreenMode->setCurrentIndex(0);
|
||||
|
||||
for (const std::string& mode_name : fullscreen_modes)
|
||||
{
|
||||
m_ui.fullscreenMode->addItem(QString::fromStdString(mode_name));
|
||||
|
||||
if (mode_name == current_mode)
|
||||
m_ui.fullscreenMode->setCurrentIndex(m_ui.fullscreenMode->count() - 1);
|
||||
}
|
||||
|
||||
// disable it if we don't have a choice
|
||||
m_ui.fullscreenMode->setEnabled(!fullscreen_modes.empty());
|
||||
}
|
||||
}
|
||||
|
||||
void DisplaySettingsWidget::onGPUAdapterIndexChanged()
|
||||
@@ -170,3 +197,16 @@ void DisplaySettingsWidget::onGPUAdapterIndexChanged()
|
||||
|
||||
m_host_interface->SetStringSettingValue("GPU", "Adapter", m_ui.adapter->currentText().toUtf8().constData());
|
||||
}
|
||||
|
||||
void DisplaySettingsWidget::onGPUFullscreenModeIndexChanged()
|
||||
{
|
||||
if (m_ui.fullscreenMode->currentIndex() == 0)
|
||||
{
|
||||
// default
|
||||
m_host_interface->RemoveSettingValue("GPU", "FullscreenMode");
|
||||
return;
|
||||
}
|
||||
|
||||
m_host_interface->SetStringSettingValue("GPU", "FullscreenMode",
|
||||
m_ui.fullscreenMode->currentText().toUtf8().constData());
|
||||
}
|
||||
@@ -17,8 +17,9 @@ public:
|
||||
~DisplaySettingsWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void populateGPUAdapters();
|
||||
void populateGPUAdaptersAndResolutions();
|
||||
void onGPUAdapterIndexChanged();
|
||||
void onGPUFullscreenModeIndexChanged();
|
||||
|
||||
private:
|
||||
void setupAdditionalUi();
|
||||
|
||||
@@ -52,7 +52,17 @@
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="adapter"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Fullscreen Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="fullscreenMode"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="vsync">
|
||||
<property name="text">
|
||||
<string>VSync</string>
|
||||
|
||||
@@ -87,13 +87,20 @@ QtDisplayWidget* MainWindow::createDisplay(QThread* worker_thread, const QString
|
||||
Assert(!m_host_display && !m_display_widget);
|
||||
Assert(!fullscreen || !render_to_main);
|
||||
|
||||
const std::string fullscreen_mode = m_host_interface->GetStringSettingValue("GPU", "FullscreenMode", "");
|
||||
const bool is_exclusive_fullscreen = (fullscreen && !fullscreen_mode.empty());
|
||||
|
||||
m_display_widget = new QtDisplayWidget((!fullscreen && render_to_main) ? m_ui.mainContainer : nullptr);
|
||||
m_display_widget->setWindowTitle(windowTitle());
|
||||
m_display_widget->setWindowIcon(windowIcon());
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
m_display_widget->showFullScreen();
|
||||
if (!is_exclusive_fullscreen)
|
||||
m_display_widget->showFullScreen();
|
||||
else
|
||||
m_display_widget->showNormal();
|
||||
|
||||
m_display_widget->setCursor(Qt::BlankCursor);
|
||||
}
|
||||
else if (!render_to_main)
|
||||
@@ -126,6 +133,9 @@ QtDisplayWidget* MainWindow::createDisplay(QThread* worker_thread, const QString
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (is_exclusive_fullscreen)
|
||||
setDisplayFullscreen(fullscreen_mode);
|
||||
|
||||
m_host_display->DoneRenderContextCurrent();
|
||||
return m_display_widget;
|
||||
}
|
||||
@@ -134,6 +144,8 @@ QtDisplayWidget* MainWindow::updateDisplay(QThread* worker_thread, bool fullscre
|
||||
{
|
||||
const bool is_fullscreen = m_display_widget->isFullScreen();
|
||||
const bool is_rendering_to_main = (!is_fullscreen && m_display_widget->parent());
|
||||
const std::string fullscreen_mode = m_host_interface->GetStringSettingValue("GPU", "FullscreenMode", "");
|
||||
const bool is_exclusive_fullscreen = (fullscreen && !fullscreen_mode.empty());
|
||||
if (fullscreen == is_fullscreen && is_rendering_to_main == render_to_main)
|
||||
return m_display_widget;
|
||||
|
||||
@@ -146,7 +158,10 @@ QtDisplayWidget* MainWindow::updateDisplay(QThread* worker_thread, bool fullscre
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
m_display_widget->showFullScreen();
|
||||
if (!is_exclusive_fullscreen)
|
||||
m_display_widget->showFullScreen();
|
||||
else
|
||||
m_display_widget->showNormal();
|
||||
m_display_widget->setCursor(Qt::BlankCursor);
|
||||
}
|
||||
else if (!render_to_main)
|
||||
@@ -174,6 +189,9 @@ QtDisplayWidget* MainWindow::updateDisplay(QThread* worker_thread, bool fullscre
|
||||
if (!m_host_display->ChangeRenderWindow(wi.value()))
|
||||
Panic("Failed to recreate surface on new widget.");
|
||||
|
||||
if (is_exclusive_fullscreen)
|
||||
setDisplayFullscreen(fullscreen_mode);
|
||||
|
||||
m_display_widget->setFocus();
|
||||
|
||||
QSignalBlocker blocker(m_ui.actionFullscreen);
|
||||
@@ -181,6 +199,23 @@ QtDisplayWidget* MainWindow::updateDisplay(QThread* worker_thread, bool fullscre
|
||||
return m_display_widget;
|
||||
}
|
||||
|
||||
void MainWindow::setDisplayFullscreen(const std::string& fullscreen_mode)
|
||||
{
|
||||
u32 width, height;
|
||||
float refresh_rate;
|
||||
bool result = false;
|
||||
|
||||
if (CommonHostInterface::ParseFullscreenMode(fullscreen_mode, &width, &height, &refresh_rate))
|
||||
{
|
||||
result = m_host_display->SetFullscreen(true, width, height, refresh_rate);
|
||||
if (!result)
|
||||
{
|
||||
m_host_interface->AddOSDMessage(
|
||||
m_host_interface->TranslateStdString("OSDMessage", "Failed to acquire exclusive fullscreen."), 20.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::destroyDisplay()
|
||||
{
|
||||
DebugAssert(m_host_display && m_display_widget);
|
||||
|
||||
@@ -105,6 +105,7 @@ private:
|
||||
void saveDisplayWindowGeometryToConfig();
|
||||
void restoreDisplayWindowGeometryFromConfig();
|
||||
void destroyDisplayWidget();
|
||||
void setDisplayFullscreen(const std::string& fullscreen_mode);
|
||||
SettingsDialog* getSettingsDialog();
|
||||
void doSettings(SettingsDialog::Category category = SettingsDialog::Category::Count);
|
||||
void updateDebugMenuCPUExecutionMode();
|
||||
|
||||
@@ -435,6 +435,15 @@ void QtHostInterface::onHostDisplayWindowResized(int width, int height)
|
||||
// re-render the display, since otherwise it will be out of date and stretched if paused
|
||||
if (!System::IsShutdown())
|
||||
{
|
||||
if (m_is_exclusive_fullscreen && !m_display->IsFullscreen())
|
||||
{
|
||||
// we lost exclusive fullscreen
|
||||
AddOSDMessage(TranslateStdString("OSDMessage", "Lost exclusive fullscreen."), 20.0f);
|
||||
m_is_exclusive_fullscreen = false;
|
||||
m_is_fullscreen = false;
|
||||
updateDisplayState();
|
||||
}
|
||||
|
||||
g_gpu->UpdateResolutionScale();
|
||||
renderDisplay();
|
||||
}
|
||||
@@ -495,6 +504,7 @@ bool QtHostInterface::AcquireHostDisplay()
|
||||
}
|
||||
|
||||
connectDisplaySignals(display_widget);
|
||||
m_is_exclusive_fullscreen = m_display->IsFullscreen();
|
||||
ImGui::NewFrame();
|
||||
return true;
|
||||
}
|
||||
@@ -551,6 +561,7 @@ void QtHostInterface::updateDisplayState()
|
||||
Panic("Failed to make device context current after updating");
|
||||
|
||||
connectDisplaySignals(display_widget);
|
||||
m_is_exclusive_fullscreen = m_display->IsFullscreen();
|
||||
|
||||
if (!System::IsShutdown())
|
||||
{
|
||||
|
||||
@@ -264,4 +264,5 @@ private:
|
||||
|
||||
bool m_is_rendering_to_main = false;
|
||||
bool m_is_fullscreen = false;
|
||||
bool m_is_exclusive_fullscreen = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user