Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add renderer settings to mitigate blurry text for some graphics devices #5853

Merged
merged 1 commit into from
May 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/cascadia/SettingsSchema.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Properties listed below affect the entire window, regardless of the profile sett
| `wordDelimiters` | Optional | String | <code>&nbsp;&#x2f;&#x5c;&#x28;&#x29;&#x22;&#x27;&#x2d;&#x3a;&#x2c;&#x2e;&#x3b;&#x3c;&#x3e;&#x7e;&#x21;&#x40;&#x23;&#x24;&#x25;&#x5e;&#x26;&#x2a;&#x7c;&#x2b;&#x3d;&#x5b;&#x5d;&#x7b;&#x7d;&#x7e;&#x3f;│</code><br>_(`│` is `U+2502 BOX DRAWINGS LIGHT VERTICAL`)_ | Determines the delimiters used in a double click selection. |
| `confirmCloseAllTabs` | Optional | Boolean | `true` | When set to `true` closing a window with multiple tabs open WILL require confirmation. When set to `false` closing a window with multiple tabs open WILL NOT require confirmation. |
| `disabledProfileSources` | Optional | Array[String] | `[]` | Disables all the dynamic profile generators in this list, preventing them from adding their profiles to the list of profiles on startup. This array can contain any combination of `Windows.Terminal.Wsl`, `Windows.Terminal.Azure`, or `Windows.Terminal.PowershellCore`. For more information, see [UsingJsonSettings.md](https://github.com/microsoft/terminal/blob/master/doc/user-docs/UsingJsonSettings.md#dynamic-profiles) |
| `experimental.rendering.forceFullRepaint` | Optional | Boolean | `false` | 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. |
| `experimental.rendering.software` | Optional | Boolean | `false` | When set to true, we will use the software renderer (a.k.a. WARP) instead of the hardware one. |

## Profiles
Properties listed below are specific to each unique profile.
Expand Down
12 changes: 10 additions & 2 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,14 @@
},
"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.",
"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.",
"type": "boolean"
},
"initialCols": {
"default": 120,
"description": "The number of columns displayed in the window upon first load.",
Expand Down Expand Up @@ -332,7 +340,7 @@
"description": "The number of rows to scroll at a time with the mouse wheel. This will override the system setting if the value is not zero or \"system\".",
"maximum": 999,
"minimum": 0,
"type": ["integer", "string"]
"type": [ "integer", "string" ]
},
"keybindings": {
"description": "Properties are specific to each custom key binding.",
Expand Down Expand Up @@ -383,7 +391,7 @@
"confirmCloseAllTabs": {
"default": true,
"description": "When set to \"true\" closing a window with multiple tabs open will require confirmation. When set to \"false\", the confirmation dialog will not appear.",
"type":"boolean"
"type": "boolean"
}
},
"required": [
Expand Down
23 changes: 23 additions & 0 deletions src/cascadia/TerminalApp/GlobalAppSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ static constexpr std::wstring_view LightThemeValue{ L"light" };
static constexpr std::wstring_view DarkThemeValue{ L"dark" };
static constexpr std::wstring_view SystemThemeValue{ L"system" };

static constexpr std::string_view ForceFullRepaintRenderingKey{ "experimental.rendering.forceFullRepaint" };
static constexpr std::string_view SoftwareRenderingKey{ "experimental.rendering.software" };

static constexpr std::string_view DebugFeaturesKey{ "debugFeatures" };

#ifdef _DEBUG
Expand Down Expand Up @@ -70,6 +73,8 @@ GlobalAppSettings::GlobalAppSettings() :
_copyOnSelect{ false },
_copyFormatting{ false },
_launchMode{ LaunchMode::DefaultMode },
_forceFullRepaintRendering{ false },
_softwareRendering{ false },
_debugFeatures{ debugFeaturesDefault }
{
}
Expand Down Expand Up @@ -187,6 +192,16 @@ void GlobalAppSettings::SetConfirmCloseAllTabs(const bool confirmCloseAllTabs) n
_confirmCloseAllTabs = confirmCloseAllTabs;
}

bool GlobalAppSettings::GetForceFullRepaintRendering() noexcept
{
return _forceFullRepaintRendering;
}

bool GlobalAppSettings::GetSoftwareRendering() noexcept
{
return _softwareRendering;
}

bool GlobalAppSettings::DebugFeaturesEnabled() const noexcept
{
return _debugFeatures;
Expand Down Expand Up @@ -230,6 +245,8 @@ void GlobalAppSettings::ApplyToSettings(TerminalSettings& settings) const noexce

settings.WordDelimiters(_wordDelimiters);
settings.CopyOnSelect(_copyOnSelect);
settings.ForceFullRepaintRendering(_forceFullRepaintRendering);
settings.SoftwareRendering(_softwareRendering);
}

// Method Description:
Expand Down Expand Up @@ -259,6 +276,8 @@ Json::Value GlobalAppSettings::ToJson() const
jsonObject[JsonKey(KeybindingsKey)] = _keybindings->ToJson();
jsonObject[JsonKey(ConfirmCloseAllKey)] = _confirmCloseAllTabs;
jsonObject[JsonKey(SnapToGridOnResizeKey)] = _SnapToGridOnResize;
jsonObject[JsonKey(ForceFullRepaintRenderingKey)] = _forceFullRepaintRendering;
jsonObject[JsonKey(SoftwareRenderingKey)] = _softwareRendering;
jsonObject[JsonKey(DebugFeaturesKey)] = _debugFeatures;

return jsonObject;
Expand Down Expand Up @@ -350,6 +369,10 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)

JsonUtils::GetBool(json, SnapToGridOnResizeKey, _SnapToGridOnResize);

JsonUtils::GetBool(json, ForceFullRepaintRenderingKey, _forceFullRepaintRendering);

JsonUtils::GetBool(json, SoftwareRenderingKey, _softwareRendering);

// GetBool will only override the current value if the key exists
JsonUtils::GetBool(json, DebugFeaturesKey, _debugFeatures);
}
Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalApp/GlobalAppSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class TerminalApp::GlobalAppSettings final
winrt::TerminalApp::LaunchMode GetLaunchMode() const noexcept;
void SetLaunchMode(const winrt::TerminalApp::LaunchMode launchMode);

bool GetForceFullRepaintRendering() noexcept;
bool GetSoftwareRendering() noexcept;

bool DebugFeaturesEnabled() const noexcept;

Json::Value ToJson() const;
Expand Down Expand Up @@ -118,6 +121,9 @@ class TerminalApp::GlobalAppSettings final

winrt::TerminalApp::LaunchMode _launchMode;

bool _softwareRendering;
bool _forceFullRepaintRendering;

bool _debugFeatures;

static winrt::Windows::UI::Xaml::ElementTheme _ParseTheme(const std::wstring& themeString) noexcept;
Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,9 +586,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation

_terminal->CreateFromSettings(_settings, renderTarget);

// TODO:GH#3927 - Make it possible to hot-reload this setting. Right
// TODO:GH#3927 - Make it possible to hot-reload these settings. Right
// here, the setting will only be used when the Terminal is initialized.
dxEngine->SetRetroTerminalEffects(_settings.RetroTerminalEffect());
dxEngine->SetForceFullRepaintRendering(_settings.ForceFullRepaintRendering());
dxEngine->SetSoftwareRendering(_settings.SoftwareRendering());

// TODO:GH#3927 - hot-reload this one too
// Update DxEngine's AntialiasingMode
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettings/IControlSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ namespace Microsoft.Terminal.Settings

UInt32 SelectionBackground;
Boolean RetroTerminalEffect;
Boolean ForceFullRepaintRendering;
Boolean SoftwareRendering;

TextAntialiasingMode AntialiasingMode;
};
Expand Down
25 changes: 23 additions & 2 deletions src/cascadia/TerminalSettings/TerminalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_backgroundImageVerticalAlignment{ winrt::Windows::UI::Xaml::VerticalAlignment::Center },
_keyBindings{ nullptr },
_scrollbarState{ ScrollbarState::Visible },
_antialiasingMode{ TextAntialiasingMode::Grayscale }

_antialiasingMode{ TextAntialiasingMode::Grayscale },
_forceFullRepaintRendering{ false },
_softwareRendering{ false }
{
}

Expand Down Expand Up @@ -387,6 +388,26 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
_retroTerminalEffect = value;
}

bool TerminalSettings::ForceFullRepaintRendering() noexcept
{
return _forceFullRepaintRendering;
}

void TerminalSettings::ForceFullRepaintRendering(bool value) noexcept
{
_forceFullRepaintRendering = value;
}

bool TerminalSettings::SoftwareRendering() noexcept
{
return _softwareRendering;
}

void TerminalSettings::SoftwareRendering(bool value) noexcept
{
_softwareRendering = value;
}

Settings::TextAntialiasingMode TerminalSettings::AntialiasingMode() const noexcept
{
return _antialiasingMode;
Expand Down
8 changes: 8 additions & 0 deletions src/cascadia/TerminalSettings/terminalsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
bool RetroTerminalEffect() noexcept;
void RetroTerminalEffect(bool value) noexcept;

bool ForceFullRepaintRendering() noexcept;
void ForceFullRepaintRendering(bool value) noexcept;

bool SoftwareRendering() noexcept;
void SoftwareRendering(bool value) noexcept;

TextAntialiasingMode AntialiasingMode() const noexcept;
void AntialiasingMode(winrt::Microsoft::Terminal::Settings::TextAntialiasingMode const& value) noexcept;

Expand Down Expand Up @@ -143,6 +149,8 @@ namespace winrt::Microsoft::Terminal::Settings::implementation
Settings::ScrollbarState _scrollbarState;

bool _retroTerminalEffect;
bool _forceFullRepaintRendering;
bool _softwareRendering;

Settings::TextAntialiasingMode _antialiasingMode;
};
Expand Down
44 changes: 33 additions & 11 deletions src/renderer/dx/DxRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ DxEngine::DxEngine() :
_boxDrawingEffect{},
_haveDeviceResources{ false },
_retroTerminalEffects{ false },
_forceFullRepaintRendering{ false },
_softwareRendering{ false },
_antialiasingMode{ D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE },
_defaultTextBackgroundOpacity{ 1.0f },
_hwndTarget{ static_cast<HWND>(INVALID_HANDLE_VALUE) },
Expand Down Expand Up @@ -387,16 +389,23 @@ try
// Trying hardware first for maximum performance, then trying WARP (software) renderer second
// in case we're running inside a downlevel VM where hardware passthrough isn't enabled like
// for Windows 7 in a VM.
const auto hardwareResult = D3D11CreateDevice(nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
DeviceFlags,
FeatureLevels.data(),
gsl::narrow_cast<UINT>(FeatureLevels.size()),
D3D11_SDK_VERSION,
&_d3dDevice,
nullptr,
&_d3dDeviceContext);
HRESULT hardwareResult = E_NOT_SET;

// If we're not forcing software rendering, try hardware first.
// Otherwise, let the error state fall down and create with the software renderer directly.
if (!_softwareRendering)
{
hardwareResult = D3D11CreateDevice(nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
DeviceFlags,
FeatureLevels.data(),
gsl::narrow_cast<UINT>(FeatureLevels.size()),
D3D11_SDK_VERSION,
&_d3dDevice,
nullptr,
&_d3dDeviceContext);
}

if (FAILED(hardwareResult))
{
Expand Down Expand Up @@ -676,6 +685,16 @@ void DxEngine::SetRetroTerminalEffects(bool enable) noexcept
_retroTerminalEffects = enable;
}

void DxEngine::SetForceFullRepaintRendering(bool enable) noexcept
{
_forceFullRepaintRendering = enable;
}

void DxEngine::SetSoftwareRendering(bool enable) noexcept
{
_softwareRendering = enable;
}

Microsoft::WRL::ComPtr<IDXGISwapChain1> DxEngine::GetSwapChain()
{
if (_dxgiSwapChain.Get() == nullptr)
Expand Down Expand Up @@ -897,11 +916,14 @@ try
{
RETURN_HR_IF(E_NOT_VALID_STATE, _isPainting); // invalid to start a paint while painting.

// If someone explicitly requested differential rendering off, then we need to invalidate everything
// so the entire frame is repainted.
//
// If retro terminal effects are on, we must invalidate everything for them to draw correctly.
// Yes, this will further impact the performance of retro terminal effects.
// But we're talking about running the entire display pipeline through a shader for
// cosmetic effect, so performance isn't likely the top concern with this feature.
if (_retroTerminalEffects)
if (_forceFullRepaintRendering || _retroTerminalEffects)
{
_invalidMap.set_all();
}
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/dx/DxRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ namespace Microsoft::Console::Render

void SetRetroTerminalEffects(bool enable) noexcept;

void SetForceFullRepaintRendering(bool enable) noexcept;

void SetSoftwareRendering(bool enable) noexcept;

::Microsoft::WRL::ComPtr<IDXGISwapChain1> GetSwapChain();

// IRenderEngine Members
Expand Down Expand Up @@ -190,6 +194,10 @@ namespace Microsoft::Console::Render
::Microsoft::WRL::ComPtr<ID3D11SamplerState> _samplerState;
::Microsoft::WRL::ComPtr<ID3D11Texture2D> _framebufferCapture;

// Preferences and overrides
bool _softwareRendering;
bool _forceFullRepaintRendering;

D2D1_TEXT_ANTIALIAS_MODE _antialiasingMode;

float _defaultTextBackgroundOpacity;
Expand Down