Enable hot reload of renderer settings that aren't already hot reload capable (#6551)

## Summary of the Pull Request

## PR Checklist
* [x] Closes #3927
* [x] I work here.
* [x] Tested manually.
* [x] Requires documentation to be updated: (generate doc bug here)
* [x] Am core contributor.

## Detailed Description of the Pull Request / Additional comments
- I found four settings that weren't hot reloadable with the 3927 comment above them:
1. Experimental retro terminal effect
2. Experimental software rendering
3. Experimental full repaint rendering
4. Antialiasing settings for text

I made them all hot reloadable by telling the `TermControl` to propagate them on settings change to the `DxEngine`.
Then I set up the `DxEngine` inside the setters to only set them if they changed. And if they do change, to trigger a full repaint and/or a complete drop and recreate of the entire DX device chain (as would happen if it were lost for another reason like a user-mode graphics failure, disconnected display, etc.)
I made the boolean an atomic because the settings can be coming in off of another thread (the XAML eventing one) and the renderer is picking the status up on its thread at the top of the BeginPaint frame.

## Validation Steps Performed
- [x] Opened it up and toggled all the settings while staring at PowerShell
- [x] Opened it up and toggled all the settings while staring at something intensive like a `cacafire` fire
This commit is contained in:
Michael Niksa 2020-06-19 14:09:37 -07:00 committed by GitHub
parent dc5baab3fe
commit b91430b64d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 11 deletions

View file

@ -250,14 +250,32 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// Update our control settings
_ApplyUISettings();
// Update DxEngine's SelectionBackground
_renderEngine->SetSelectionBackground(_settings.SelectionBackground());
// Update the terminal core with its new Core settings
_terminal->UpdateSettings(_settings);
auto lock = _terminal->LockForWriting();
// Update DxEngine settings under the lock
_renderEngine->SetSelectionBackground(_settings.SelectionBackground());
_renderEngine->SetRetroTerminalEffects(_settings.RetroTerminalEffect());
_renderEngine->SetForceFullRepaintRendering(_settings.ForceFullRepaintRendering());
_renderEngine->SetSoftwareRendering(_settings.SoftwareRendering());
switch (_settings.AntialiasingMode())
{
case TextAntialiasingMode::Cleartype:
_renderEngine->SetAntialiasingMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);
break;
case TextAntialiasingMode::Aliased:
_renderEngine->SetAntialiasingMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
break;
case TextAntialiasingMode::Grayscale:
default:
_renderEngine->SetAntialiasingMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
break;
}
// Refresh our font with the renderer
const auto actualFontOldSize = _actualFont.GetSize();
_UpdateFont();
@ -611,13 +629,10 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_terminal->CreateFromSettings(_settings, renderTarget);
// 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
switch (_settings.AntialiasingMode())
{

View file

@ -84,6 +84,7 @@ DxEngine::DxEngine() :
_boxDrawingEffect{},
_haveDeviceResources{ false },
_swapChainFrameLatencyWaitableObject{ INVALID_HANDLE_VALUE },
_recreateDeviceRequested{ false },
_retroTerminalEffects{ false },
_forceFullRepaintRendering{ false },
_softwareRendering{ false },
@ -621,6 +622,9 @@ void DxEngine::_ReleaseDeviceResources() noexcept
try
{
_haveDeviceResources = false;
_pixelShaderSettingsBuffer.Reset();
_d2dBrushForeground.Reset();
_d2dBrushBackground.Reset();
@ -703,19 +707,39 @@ void DxEngine::SetCallback(std::function<void()> pfn)
}
void DxEngine::SetRetroTerminalEffects(bool enable) noexcept
try
{
_retroTerminalEffects = enable;
if (_retroTerminalEffects != enable)
{
_retroTerminalEffects = enable;
_recreateDeviceRequested = true;
LOG_IF_FAILED(InvalidateAll());
}
}
CATCH_LOG()
void DxEngine::SetForceFullRepaintRendering(bool enable) noexcept
try
{
_forceFullRepaintRendering = enable;
if (_forceFullRepaintRendering != enable)
{
_forceFullRepaintRendering = enable;
LOG_IF_FAILED(InvalidateAll());
}
}
CATCH_LOG()
void DxEngine::SetSoftwareRendering(bool enable) noexcept
try
{
_softwareRendering = enable;
if (_softwareRendering != enable)
{
_softwareRendering = enable;
_recreateDeviceRequested = true;
LOG_IF_FAILED(InvalidateAll());
}
}
CATCH_LOG()
Microsoft::WRL::ComPtr<IDXGISwapChain1> DxEngine::GetSwapChain()
{
@ -965,9 +989,13 @@ try
if (_isEnabled)
{
const auto clientSize = _GetClientSize();
if (!_haveDeviceResources)
// If we don't have device resources or if someone has requested that we
// recreate the device... then make new resources. (Create will dump the old ones.)
if (!_haveDeviceResources || _recreateDeviceRequested)
{
RETURN_IF_FAILED(_CreateDeviceResources(true));
_recreateDeviceRequested = false;
}
else if (_displaySizePixels != clientSize || _prevScale != _scale)
{
@ -2172,9 +2200,15 @@ void DxEngine::SetSelectionBackground(const COLORREF color) noexcept
// Return Value:
// - N/A
void DxEngine::SetAntialiasingMode(const D2D1_TEXT_ANTIALIAS_MODE antialiasingMode) noexcept
try
{
_antialiasingMode = antialiasingMode;
if (_antialiasingMode != antialiasingMode)
{
_antialiasingMode = antialiasingMode;
LOG_IF_FAILED(InvalidateAll());
}
}
CATCH_LOG()
// Method Description:
// - Update our tracker of the opacity of our background. We can only

View file

@ -175,6 +175,7 @@ namespace Microsoft::Console::Render
::Microsoft::WRL::ComPtr<ID2D1StrokeStyle> _strokeStyle;
// Device-Dependent Resources
bool _recreateDeviceRequested;
bool _haveDeviceResources;
::Microsoft::WRL::ComPtr<ID3D11Device> _d3dDevice;
::Microsoft::WRL::ComPtr<ID3D11DeviceContext> _d3dDeviceContext;