Skip to content

Commit

Permalink
AtlasEngine: Make Direct2D/3D and Present1 configurable (#16939)
Browse files Browse the repository at this point in the history
This implements `SetForceFullRepaintRendering` and adds a new
`SetGraphicsAPI` function. The former toggles `Present1` on and off
and the latter allows users to explicitly request Direct2D/3D.

On top of these changes I did a minor cleanup of the interface,
because now that DxRenderer is gone we don't need all that anymore.

Closes #14254
Closes #16747

## Validation Steps Performed
* Toggling Direct2D on/off changes colored ligature support ✅
* Toggling Present1 on/off can be observed in a debugger ✅
* Toggling WARP on/off changes GPU metrics ✅

---------

Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
  • Loading branch information
lhecker and DHowett committed Mar 26, 2024
1 parent 501522d commit a67a132
Show file tree
Hide file tree
Showing 49 changed files with 351 additions and 314 deletions.
16 changes: 12 additions & 4 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2332,12 +2332,20 @@
},
"type": "array"
},
"experimental.rendering.forceFullRepaint": {
"description": "When set to true, we will redraw the entire screen each frame. When set to false, we will render only the updates to the screen between frames.",
"rendering.graphicsAPI": {
"description": "Direct3D 11 provides a more performant and feature-rich experience, whereas Direct2D is more stable. The default option \"Automatic\" will pick the API that best fits your graphics hardware. If you experience significant issues, consider using Direct2D.",
"type": "string",
"enum": [
"direct2d",
"direct3d11"
]
},
"rendering.disablePartialInvalidation": {
"description": "By default, the text renderer uses a FLIP_SEQUENTIAL Swap Chain and declares dirty rectangles via the Present1 API. When this setting is enabled, a FLIP_DISCARD Swap Chain will be used instead, and no dirty rectangles will be declared. Whether one or the other is better depends on your hardware and various other factors.",
"type": "boolean"
},
"experimental.rendering.software": {
"description": "When set to true, we will use the software renderer (a.k.a. WARP) instead of the hardware one.",
"rendering.software": {
"description": "When enabled, the terminal will use a software rasterizer (WARP). This setting should be left disabled under almost all circumstances.",
"type": "boolean"
},
"experimental.input.forceVT": {
Expand Down
54 changes: 34 additions & 20 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
#include <dsound.h>

#include <DefaultSettings.h>
#include <unicode.hpp>
#include <utils.hpp>
#include <WinUser.h>
#include <LibraryResources.h>

#include "EventArgs.h"
#include "../../buffer/out/search.h"
#include "../../renderer/atlas/AtlasEngine.h"
#include "../../renderer/base/renderer.hpp"
#include "../../renderer/uia/UiaRenderer.hpp"

#include "ControlCore.g.cpp"
#include "SelectionColor.g.cpp"
Expand All @@ -43,26 +42,26 @@ constexpr const auto SearchAfterChangeDelay = std::chrono::milliseconds(200);

namespace winrt::Microsoft::Terminal::Control::implementation
{
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const til::color& c)
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const til::color& c) noexcept
{
Core::OptionalColor result;
result.Color = c;
result.HasValue = true;
return result;
}
static winrt::Microsoft::Terminal::Core::OptionalColor OptionalFromColor(const std::optional<til::color>& c)

static ::Microsoft::Console::Render::Atlas::GraphicsAPI parseGraphicsAPI(GraphicsAPI api) noexcept
{
Core::OptionalColor result;
if (c.has_value())
{
result.Color = *c;
result.HasValue = true;
}
else
using GA = ::Microsoft::Console::Render::Atlas::GraphicsAPI;
switch (api)
{
result.HasValue = false;
case GraphicsAPI::Direct2D:
return GA::Direct2D;
case GraphicsAPI::Direct3D11:
return GA::Direct3D11;
default:
return GA::Automatic;
}
return result;
}

TextColor SelectionColor::AsTextColor() const noexcept
Expand Down Expand Up @@ -388,7 +387,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_renderEngine->SetRetroTerminalEffect(_settings->RetroTerminalEffect());
_renderEngine->SetPixelShaderPath(_settings->PixelShaderPath());
_renderEngine->SetPixelShaderImagePath(_settings->PixelShaderImagePath());
_renderEngine->SetForceFullRepaintRendering(_settings->ForceFullRepaintRendering());
_renderEngine->SetGraphicsAPI(parseGraphicsAPI(_settings->GraphicsAPI()));
_renderEngine->SetDisablePartialInvalidation(_settings->DisablePartialInvalidation());
_renderEngine->SetSoftwareRendering(_settings->SoftwareRendering());

_updateAntiAliasingMode();
Expand All @@ -397,8 +397,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// GH#11315: Always do this, even if they don't have acrylic on.
_renderEngine->EnableTransparentBackground(_isBackgroundTransparent());

THROW_IF_FAILED(_renderEngine->Enable());

_initializedTerminal.store(true, std::memory_order_relaxed);
} // scope for TerminalLock

Expand Down Expand Up @@ -883,7 +881,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return;
}

_renderEngine->SetForceFullRepaintRendering(_settings->ForceFullRepaintRendering());
_renderEngine->SetGraphicsAPI(parseGraphicsAPI(_settings->GraphicsAPI()));
_renderEngine->SetDisablePartialInvalidation(_settings->DisablePartialInvalidation());
_renderEngine->SetSoftwareRendering(_settings->SoftwareRendering());
// Inform the renderer of our opacity
_renderEngine->EnableTransparentBackground(_isBackgroundTransparent());
Expand Down Expand Up @@ -946,6 +945,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}

Control::IControlSettings ControlCore::Settings()
{
return *_settings;
}

Control::IControlAppearance ControlCore::FocusedAppearance() const
{
return *_settings->FocusedAppearance();
}

Control::IControlAppearance ControlCore::UnfocusedAppearance() const
{
return *_settings->UnfocusedAppearance();
}

void ControlCore::_updateAntiAliasingMode()
{
D2D1_TEXT_ANTIALIAS_MODE mode;
Expand Down Expand Up @@ -1960,13 +1974,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
UpdateSelectionMarkers.raise(*this, winrt::make<implementation::UpdateSelectionMarkersEventArgs>(!showMarkers));
}

void ControlCore::AttachUiaEngine(::Microsoft::Console::Render::IRenderEngine* const pEngine)
void ControlCore::AttachUiaEngine(::Microsoft::Console::Render::UiaEngine* const pEngine)
{
// _renderer will always exist since it's introduced in the ctor
const auto lock = _terminal->LockForWriting();
_renderer->AddRenderEngine(pEngine);
}
void ControlCore::DetachUiaEngine(::Microsoft::Console::Render::IRenderEngine* const pEngine)
void ControlCore::DetachUiaEngine(::Microsoft::Console::Render::UiaEngine* const pEngine)
{
const auto lock = _terminal->LockForWriting();
_renderer->RemoveRenderEngine(pEngine);
Expand Down
28 changes: 19 additions & 9 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,22 @@
#include "ControlCore.g.h"
#include "SelectionColor.g.h"
#include "CommandHistoryContext.g.h"

#include "ControlSettings.h"
#include "../../audio/midi/MidiAudio.hpp"
#include "../../renderer/base/Renderer.hpp"
#include "../../buffer/out/search.h"
#include "../../cascadia/TerminalCore/Terminal.hpp"
#include "../buffer/out/search.h"
#include "../buffer/out/TextColor.h"
#include "../../renderer/inc/FontInfoDesired.hpp"

namespace Microsoft::Console::Render::Atlas
{
class AtlasEngine;
}

namespace Microsoft::Console::Render
{
class UiaEngine;
}

namespace ControlUnitTests
{
Expand Down Expand Up @@ -82,9 +92,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation

void UpdateSettings(const Control::IControlSettings& settings, const IControlAppearance& newAppearance);
void ApplyAppearance(const bool& focused);
Control::IControlSettings Settings() { return *_settings; };
Control::IControlAppearance FocusedAppearance() const { return *_settings->FocusedAppearance(); };
Control::IControlAppearance UnfocusedAppearance() const { return *_settings->UnfocusedAppearance(); };
Control::IControlSettings Settings();
Control::IControlAppearance FocusedAppearance() const;
Control::IControlAppearance UnfocusedAppearance() const;
bool HasUnfocusedAppearance() const;

winrt::Microsoft::Terminal::Core::Scheme ColorScheme() const noexcept;
Expand Down Expand Up @@ -219,8 +229,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const bool isOnOriginalPosition,
bool& selectionNeedsToBeCopied);

void AttachUiaEngine(::Microsoft::Console::Render::IRenderEngine* const pEngine);
void DetachUiaEngine(::Microsoft::Console::Render::IRenderEngine* const pEngine);
void AttachUiaEngine(::Microsoft::Console::Render::UiaEngine* const pEngine);
void DetachUiaEngine(::Microsoft::Console::Render::UiaEngine* const pEngine);

bool IsInReadOnlyMode() const;
void ToggleReadOnlyMode();
Expand Down Expand Up @@ -306,7 +316,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// As _renderer has a dependency on _renderEngine (through a raw pointer)
// we must ensure the _renderer is deallocated first.
// (C++ class members are destroyed in reverse order.)
std::unique_ptr<::Microsoft::Console::Render::IRenderEngine> _renderEngine{ nullptr };
std::unique_ptr<::Microsoft::Console::Render::Atlas::AtlasEngine> _renderEngine{ nullptr };
std::unique_ptr<::Microsoft::Console::Render::Renderer> _renderer{ nullptr };

::Search _searcher;
Expand Down
8 changes: 7 additions & 1 deletion src/cascadia/TerminalControl/EventArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ namespace Microsoft.Terminal.Control
All = 0xffffffff
};

enum GraphicsAPI
{
Automatic,
Direct2D,
Direct3D11,
};

runtimeclass FontSizeChangedArgs
{
Expand Down Expand Up @@ -90,7 +96,7 @@ namespace Microsoft.Terminal.Control
{
Boolean ShowOrHide { get; };
}

runtimeclass UpdateSelectionMarkersEventArgs
{
Boolean ClearMarkers { get; };
Expand Down
1 change: 0 additions & 1 deletion src/cascadia/TerminalControl/HwndTerminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ HRESULT HwndTerminal::Initialize()

auto engine = std::make_unique<::Microsoft::Console::Render::AtlasEngine>();
RETURN_IF_FAILED(engine->SetHwnd(_hwnd.get()));
RETURN_IF_FAILED(engine->Enable());
_renderer->AddRenderEngine(engine.get());

_UpdateFont(USER_DEFAULT_SCREEN_DPI);
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalControl/IControlSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ namespace Microsoft.Terminal.Control
TextAntialiasingMode AntialiasingMode { get; };

// Experimental Settings
Boolean ForceFullRepaintRendering { get; };
Microsoft.Terminal.Control.GraphicsAPI GraphicsAPI { get; };
Boolean DisablePartialInvalidation { get; };
Boolean SoftwareRendering { get; };
Boolean ShowMarks { get; };
Boolean UseBackgroundImageForWindow { get; };
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2409,7 +2409,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
LOG_IF_FAILED(engine->UpdateDpi(dpi));
LOG_IF_FAILED(engine->UpdateFont(desiredFont, actualFont));

const auto scale = engine->GetScaling();
const auto scale = dpi / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
const auto actualFontSize = actualFont.GetSize();

// UWP XAML scrollbars aren't guaranteed to be the same size as the
Expand Down
20 changes: 14 additions & 6 deletions src/cascadia/TerminalSettingsEditor/Rendering.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,28 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml" />
</ResourceDictionary.MergedDictionaries>

<DataTemplate x:Key="EnumComboBoxTemplate"
x:DataType="local:EnumEntry">
<TextBlock Text="{x:Bind EnumName}" />
</DataTemplate>
</ResourceDictionary>
</Page.Resources>

<StackPanel Style="{StaticResource SettingsStackStyle}">
<TextBlock x:Uid="Globals_RenderingDisclaimer"
Style="{StaticResource DisclaimerStyle}" />
<local:SettingContainer x:Uid="Globals_GraphicsAPI">
<ComboBox AutomationProperties.AccessibilityView="Content"
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind ViewModel.GraphicsAPIList}"
SelectedItem="{x:Bind ViewModel.CurrentGraphicsAPI, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}" />
</local:SettingContainer>

<!-- Force Full Repaint -->
<local:SettingContainer x:Uid="Globals_ForceFullRepaint">
<ToggleSwitch IsOn="{x:Bind ViewModel.ForceFullRepaintRendering, Mode=TwoWay}"
<local:SettingContainer x:Uid="Globals_DisablePartialInvalidation">
<ToggleSwitch IsOn="{x:Bind ViewModel.DisablePartialInvalidation, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>

<!-- Software Rendering -->
<local:SettingContainer x:Uid="Globals_SoftwareRendering">
<ToggleSwitch IsOn="{x:Bind ViewModel.SoftwareRendering, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
Expand Down
6 changes: 5 additions & 1 deletion src/cascadia/TerminalSettingsEditor/RenderingViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@

#include "pch.h"
#include "RenderingViewModel.h"

#include "EnumEntry.h"

#include "RenderingViewModel.g.cpp"

using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Terminal::Settings::Model;

namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
RenderingViewModel::RenderingViewModel(Model::CascadiaSettings settings) noexcept :
RenderingViewModel::RenderingViewModel(CascadiaSettings settings) noexcept :
_settings{ std::move(settings) }
{
INITIALIZE_BINDABLE_ENUM_SETTING(GraphicsAPI, GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, L"Globals_GraphicsAPI_", L"Text");
}
}
4 changes: 3 additions & 1 deletion src/cascadia/TerminalSettingsEditor/RenderingViewModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include "RenderingViewModel.g.h"
#include "Utils.h"
#include "ViewModelHelpers.h"

namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Expand All @@ -12,7 +13,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
explicit RenderingViewModel(Model::CascadiaSettings settings) noexcept;

PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), ForceFullRepaintRendering);
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.GlobalSettings().GraphicsAPI);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DisablePartialInvalidation);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), SoftwareRendering);

private:
Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalSettingsEditor/RenderingViewModel.idl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ namespace Microsoft.Terminal.Settings.Editor
{
RenderingViewModel(Microsoft.Terminal.Settings.Model.CascadiaSettings settings);

PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ForceFullRepaintRendering);
IInspectable CurrentGraphicsAPI;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> GraphicsAPIList { get; };
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, DisablePartialInvalidation);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, SoftwareRendering);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,13 @@
<value>Die Terminalanwendung, die gestartet wird, wenn eine Befehlszeilenanwendung ohne vorhandene Sitzung gestartet wird, beispielsweise vom Startmenü oder über das Dialogfeld "Ausführen".</value>
<comment>A description to clarify that the dropdown choice for default terminal will tell the operating system which Terminal application (Windows Terminal, the preview build, the legacy inbox window, or a 3rd party one) to use when starting a command line tool like CMD or Powershell that does not already have a window.</comment>
</data>
<data name="Globals_ForceFullRepaint.Header" xml:space="preserve">
<data name="Globals_DisablePartialInvalidation.Header" xml:space="preserve">
<value>Gesamten Bildschirm beim Anzeigen von Updates aktualisieren</value>
<comment>Header for a control to toggle the "force full repaint" setting. When enabled, the app renders new content between screen frames.</comment>
</data>
<data name="Globals_ForceFullRepaint.HelpText" xml:space="preserve">
<data name="Globals_DisablePartialInvalidation.HelpText" xml:space="preserve">
<value>Wenn diese Option deaktiviert ist, rendert das Terminal die Aktualisierungen nur zwischen den Frames auf den Bildschirm.</value>
<comment>A description for what the "force full repaint" setting does. Presented near "Globals_ForceFullRepaint.Header".</comment>
<comment>A description for what the "force full repaint" setting does. Presented near "Globals_DisablePartialInvalidation.Header".</comment>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Spalten</value>
Expand Down Expand Up @@ -446,10 +446,6 @@
<value>An das zuletzt verwendete Fenster auf diesem Desktop anhängen</value>
<comment>An option to choose from for the "windowing behavior" setting. When selected, new instances open in the most recently used window on this virtual desktop.</comment>
</data>
<data name="Globals_RenderingDisclaimer.Text" xml:space="preserve">
<value>Diese Einstellungen eignen sich möglicherweise für die Problembehandlung, Sie wirken sich jedoch auf die Leistung aus.</value>
<comment>A disclaimer presented at the top of a page.</comment>
</data>
<data name="Globals_ShowTitlebar.Header" xml:space="preserve">
<value>Titelleiste ausblenden (Neustart erforderlich)</value>
<comment>Header for a control to toggle whether the title bar should be shown or not. Changing this setting requires the user to relaunch the app.</comment>
Expand Down
Loading

0 comments on commit a67a132

Please sign in to comment.