Eliminate more transient allocations: Titles and invalid rectangles and bitmap runs and utf8 conversions (#8621)
## References * See also #8617 ## PR Checklist * [x] Supports #3075 * [x] I work here. * [x] Manual test. ## Detailed Description of the Pull Request / Additional comments ### Window Title Generation Every time the renderer checks the title, it's doing two bad things that I've fixed: 1. It's assembling the prefix to the full title doing a concatenation. No one ever gets just the prefix ever after it is set besides the concat. So instead of storing prefix and the title, I store the assembled prefix + title and the bare title. 2. A copy must be made because it was returning `std::wstring` instead of `std::wstring&`. Now it returns the ref. ### Dirty Area Return Every time the renderer checks the dirty area, which is sometimes multiple times per pass (regular text printing, again for selection, etc.), a vector is created off the heap to return the rectangles. The consumers only ever iterate this data. Now we return a span over a rectangle or rectangles that the engine must store itself. 1. For some renderers, it's always a constant 1 element. They update that 1 element when dirty is queried and return it in the span with a span size of 1. 2. For other renderers with more complex behavior, they're already holding a cached vector of rectangles. Now it's effectively giving out the ref to those in the span for iteration. ### Bitmap Runs The `til::bitmap` used a `std::optional<std::vector<til::rectangle>>` inside itself to cache its runs and would clear the optional when the runs became invalidated. Unfortunately doing `.reset()` to clear the optional will destroy the underlying vector and have it release its memory. We know it's about to get reallocated again, so we're just going to make it a `std::pmr::vector` and give it a memory pool. The alternative solution here was to use a `bool` and `std::vector<til::rectangle>` and just flag when the vector was invalid, but that was honestly more code changes and I love excuses to try out PMR now. Also, instead of returning the ref to the vector... I'm just returning a span now. Everyone just iterates it anyway, may as well not share the implementation detail. ### UTF-8 conversions When testing with Terminal and looking at the `conhost.exe`'s PTY renderer, it spends a TON of allocation time on converting all the UTF-16 stuff inside to UTF-8 before it sends it out the PTY. This was because `ConvertToA` was allocating a string inside itself and returning it just to have it freed after printing and looping back around again... as a PTY does. The change here is to use `til::u16u8` that accepts a buffer out parameter so the caller can just hold onto it. ## Validation Steps Performed - [x] `big.txt` in conhost.exe (GDI renderer) - [x] `big.txt` in Terminal (DX, PTY renderer) - [x] Ensure WDDM and BGFX build under Razzle with this change.
This commit is contained in:
parent
ca226d62e2
commit
525be22bd8
|
@ -182,7 +182,7 @@ public:
|
|||
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
|
||||
const COORD GetSelectionAnchor() const noexcept override;
|
||||
const COORD GetSelectionEnd() const noexcept override;
|
||||
const std::wstring GetConsoleTitle() const noexcept override;
|
||||
const std::wstring_view GetConsoleTitle() const noexcept override;
|
||||
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute) override;
|
||||
#pragma endregion
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
|
|||
SetSelectionEnd(realCoordEnd, SelectionExpansionMode::Cell);
|
||||
}
|
||||
|
||||
const std::wstring Terminal::GetConsoleTitle() const noexcept
|
||||
const std::wstring_view Terminal::GetConsoleTitle() const noexcept
|
||||
try
|
||||
{
|
||||
if (_title.has_value())
|
||||
|
|
|
@ -24,6 +24,8 @@ CONSOLE_INFORMATION::CONSOLE_INFORMATION() :
|
|||
// ExeAliasList initialized below
|
||||
_OriginalTitle(),
|
||||
_Title(),
|
||||
_Prefix(),
|
||||
_TitleAndPrefix(),
|
||||
_LinkTitle(),
|
||||
Flags(0),
|
||||
PopupCount(0),
|
||||
|
@ -115,7 +117,12 @@ ULONG CONSOLE_INFORMATION::GetCSRecursionCount()
|
|||
try
|
||||
{
|
||||
gci.SetTitle(title);
|
||||
gci.SetOriginalTitle(std::wstring(TranslateConsoleTitle(gci.GetTitle().c_str(), TRUE, FALSE)));
|
||||
|
||||
// TranslateConsoleTitle must have a null terminated string.
|
||||
// This should only happen once on startup so the copy shouldn't be costly
|
||||
// but could be eliminated by rewriting TranslateConsoleTitle.
|
||||
const std::wstring nullTerminatedTitle{ gci.GetTitle() };
|
||||
gci.SetOriginalTitle(std::wstring(TranslateConsoleTitle(nullTerminatedTitle.c_str(), TRUE, FALSE)));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -269,6 +276,7 @@ std::pair<COLORREF, COLORREF> CONSOLE_INFORMATION::LookupAttributeColors(const T
|
|||
void CONSOLE_INFORMATION::SetTitle(const std::wstring_view newTitle)
|
||||
{
|
||||
_Title = std::wstring{ newTitle.begin(), newTitle.end() };
|
||||
_TitleAndPrefix = _Prefix + _Title;
|
||||
|
||||
auto* const pRender = ServiceLocator::LocateGlobals().pRender;
|
||||
if (pRender)
|
||||
|
@ -284,9 +292,10 @@ void CONSOLE_INFORMATION::SetTitle(const std::wstring_view newTitle)
|
|||
// - newTitlePrefix: The new value to use for the title prefix
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CONSOLE_INFORMATION::SetTitlePrefix(const std::wstring& newTitlePrefix)
|
||||
void CONSOLE_INFORMATION::SetTitlePrefix(const std::wstring_view newTitlePrefix)
|
||||
{
|
||||
_TitlePrefix = newTitlePrefix;
|
||||
_Prefix = newTitlePrefix;
|
||||
_TitleAndPrefix = _Prefix + _Title;
|
||||
|
||||
auto* const pRender = ServiceLocator::LocateGlobals().pRender;
|
||||
if (pRender)
|
||||
|
@ -302,7 +311,7 @@ void CONSOLE_INFORMATION::SetTitlePrefix(const std::wstring& newTitlePrefix)
|
|||
// - originalTitle: The new value to use for the console's original title
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CONSOLE_INFORMATION::SetOriginalTitle(const std::wstring& originalTitle)
|
||||
void CONSOLE_INFORMATION::SetOriginalTitle(const std::wstring_view originalTitle)
|
||||
{
|
||||
_OriginalTitle = originalTitle;
|
||||
}
|
||||
|
@ -314,7 +323,7 @@ void CONSOLE_INFORMATION::SetOriginalTitle(const std::wstring& originalTitle)
|
|||
// - linkTitle: The new value to use for the console's link title
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CONSOLE_INFORMATION::SetLinkTitle(const std::wstring& linkTitle)
|
||||
void CONSOLE_INFORMATION::SetLinkTitle(const std::wstring_view linkTitle)
|
||||
{
|
||||
_LinkTitle = linkTitle;
|
||||
}
|
||||
|
@ -324,8 +333,8 @@ void CONSOLE_INFORMATION::SetLinkTitle(const std::wstring& linkTitle)
|
|||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a reference to the console's title.
|
||||
const std::wstring& CONSOLE_INFORMATION::GetTitle() const noexcept
|
||||
// - the console's title.
|
||||
const std::wstring_view CONSOLE_INFORMATION::GetTitle() const noexcept
|
||||
{
|
||||
return _Title;
|
||||
}
|
||||
|
@ -336,10 +345,10 @@ const std::wstring& CONSOLE_INFORMATION::GetTitle() const noexcept
|
|||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a new wstring containing the combined prefix and title.
|
||||
const std::wstring CONSOLE_INFORMATION::GetTitleAndPrefix() const
|
||||
// - the combined prefix and title.
|
||||
const std::wstring_view CONSOLE_INFORMATION::GetTitleAndPrefix() const
|
||||
{
|
||||
return _TitlePrefix + _Title;
|
||||
return _TitleAndPrefix;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -347,8 +356,8 @@ const std::wstring CONSOLE_INFORMATION::GetTitleAndPrefix() const
|
|||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a reference to the console's original title.
|
||||
const std::wstring& CONSOLE_INFORMATION::GetOriginalTitle() const noexcept
|
||||
// - the console's original title.
|
||||
const std::wstring_view CONSOLE_INFORMATION::GetOriginalTitle() const noexcept
|
||||
{
|
||||
return _OriginalTitle;
|
||||
}
|
||||
|
@ -358,8 +367,8 @@ const std::wstring& CONSOLE_INFORMATION::GetOriginalTitle() const noexcept
|
|||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - a reference to the console's link title.
|
||||
const std::wstring& CONSOLE_INFORMATION::GetLinkTitle() const noexcept
|
||||
// - the console's link title.
|
||||
const std::wstring_view CONSOLE_INFORMATION::GetLinkTitle() const noexcept
|
||||
{
|
||||
return _LinkTitle;
|
||||
}
|
||||
|
|
|
@ -1660,33 +1660,21 @@ void DoSrvPrivateRefreshWindow(_In_ const SCREEN_INFORMATION& screenInfo)
|
|||
}
|
||||
|
||||
// Get the appropriate title and length depending on the mode.
|
||||
const wchar_t* pwszTitle;
|
||||
size_t cchTitleLength;
|
||||
|
||||
if (isOriginal)
|
||||
{
|
||||
pwszTitle = gci.GetOriginalTitle().c_str();
|
||||
cchTitleLength = gci.GetOriginalTitle().length();
|
||||
}
|
||||
else
|
||||
{
|
||||
pwszTitle = gci.GetTitle().c_str();
|
||||
cchTitleLength = gci.GetTitle().length();
|
||||
}
|
||||
const std::wstring_view storedTitle = isOriginal ? gci.GetOriginalTitle() : gci.GetTitle();
|
||||
|
||||
// Always report how much space we would need.
|
||||
needed = cchTitleLength;
|
||||
needed = storedTitle.size();
|
||||
|
||||
// If we have a pointer to receive the data, then copy it out.
|
||||
if (title.has_value())
|
||||
{
|
||||
HRESULT const hr = StringCchCopyNW(title->data(), title->size(), pwszTitle, cchTitleLength);
|
||||
HRESULT const hr = StringCchCopyNW(title->data(), title->size(), storedTitle.data(), storedTitle.size());
|
||||
|
||||
// Insufficient buffer is allowed. If we return a partial string, that's still OK by historical/compat standards.
|
||||
// Just say how much we managed to return.
|
||||
if (SUCCEEDED(hr) || STRSAFE_E_INSUFFICIENT_BUFFER == hr)
|
||||
{
|
||||
written = std::min(title->size(), cchTitleLength);
|
||||
written = std::min(title->size(), storedTitle.size());
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
|
|
|
@ -318,7 +318,7 @@ const bool RenderData::IsGridLineDrawingAllowed() noexcept
|
|||
// - Retrieves the title information to be displayed in the frame/edge of the window
|
||||
// Return Value:
|
||||
// - String with title information
|
||||
const std::wstring RenderData::GetConsoleTitle() const noexcept
|
||||
const std::wstring_view RenderData::GetConsoleTitle() const noexcept
|
||||
{
|
||||
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
return gci.GetTitleAndPrefix();
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
const bool IsGridLineDrawingAllowed() noexcept override;
|
||||
|
||||
const std::wstring GetConsoleTitle() const noexcept override;
|
||||
const std::wstring_view GetConsoleTitle() const noexcept override;
|
||||
|
||||
const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
|
||||
const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
|
||||
|
|
|
@ -129,13 +129,13 @@ public:
|
|||
std::pair<COLORREF, COLORREF> LookupAttributeColors(const TextAttribute& attr) const noexcept;
|
||||
|
||||
void SetTitle(const std::wstring_view newTitle);
|
||||
void SetTitlePrefix(const std::wstring& newTitlePrefix);
|
||||
void SetOriginalTitle(const std::wstring& originalTitle);
|
||||
void SetLinkTitle(const std::wstring& linkTitle);
|
||||
const std::wstring& GetTitle() const noexcept;
|
||||
const std::wstring& GetOriginalTitle() const noexcept;
|
||||
const std::wstring& GetLinkTitle() const noexcept;
|
||||
const std::wstring GetTitleAndPrefix() const;
|
||||
void SetTitlePrefix(const std::wstring_view newTitlePrefix);
|
||||
void SetOriginalTitle(const std::wstring_view originalTitle);
|
||||
void SetLinkTitle(const std::wstring_view linkTitle);
|
||||
const std::wstring_view GetTitle() const noexcept;
|
||||
const std::wstring_view GetOriginalTitle() const noexcept;
|
||||
const std::wstring_view GetLinkTitle() const noexcept;
|
||||
const std::wstring_view GetTitleAndPrefix() const;
|
||||
|
||||
[[nodiscard]] static NTSTATUS AllocateConsole(const std::wstring_view title);
|
||||
// MSFT:16886775 : get rid of friends
|
||||
|
@ -152,7 +152,8 @@ public:
|
|||
private:
|
||||
CRITICAL_SECTION _csConsoleLock; // serialize input and output using this
|
||||
std::wstring _Title;
|
||||
std::wstring _TitlePrefix; // Eg Select, Mark - things that we manually prepend to the title.
|
||||
std::wstring _Prefix; // Eg Select, Mark - things that we manually prepend to the title.
|
||||
std::wstring _TitleAndPrefix;
|
||||
std::wstring _OriginalTitle;
|
||||
std::wstring _LinkTitle; // Path to .lnk file
|
||||
SCREEN_INFORMATION* pCurrentScreenBuffer;
|
||||
|
|
|
@ -207,10 +207,12 @@ class ApiRoutinesTests
|
|||
CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
gci.SetTitle(L"Test window title.");
|
||||
|
||||
const auto title = gci.GetTitle();
|
||||
|
||||
int const iBytesNeeded = WideCharToMultiByte(gci.OutputCP,
|
||||
0,
|
||||
gci.GetTitle().c_str(),
|
||||
-1,
|
||||
title.data(),
|
||||
gsl::narrow_cast<int>(title.size()),
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
|
@ -221,8 +223,8 @@ class ApiRoutinesTests
|
|||
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(WideCharToMultiByte(gci.OutputCP,
|
||||
0,
|
||||
gci.GetTitle().c_str(),
|
||||
-1,
|
||||
title.data(),
|
||||
gsl::narrow_cast<int>(title.size()),
|
||||
pszExpected.get(),
|
||||
iBytesNeeded,
|
||||
nullptr,
|
||||
|
@ -251,10 +253,13 @@ class ApiRoutinesTests
|
|||
VERIFY_SUCCEEDED(_pApiRoutines->GetConsoleTitleWImpl(gsl::span<wchar_t>(pwszTitle, ARRAYSIZE(pwszTitle)), cchWritten, cchNeeded));
|
||||
|
||||
VERIFY_ARE_NOT_EQUAL(0u, cchWritten);
|
||||
|
||||
const auto title = gci.GetTitle();
|
||||
|
||||
// NOTE: W version of API returns string length. A version of API returns buffer length (string + null).
|
||||
VERIFY_ARE_EQUAL(gci.GetTitle().length(), cchWritten);
|
||||
VERIFY_ARE_EQUAL(gci.GetTitle().length(), cchNeeded);
|
||||
VERIFY_ARE_EQUAL(WEX::Common::String(gci.GetTitle().c_str()), WEX::Common::String(pwszTitle));
|
||||
VERIFY_ARE_EQUAL(title.length(), cchWritten);
|
||||
VERIFY_ARE_EQUAL(title.length(), cchNeeded);
|
||||
VERIFY_ARE_EQUAL(WEX::Common::String(title.data(), gsl::narrow_cast<int>(title.size())), WEX::Common::String(pwszTitle));
|
||||
}
|
||||
|
||||
TEST_METHOD(ApiGetConsoleOriginalTitleA)
|
||||
|
@ -262,10 +267,12 @@ class ApiRoutinesTests
|
|||
CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
gci.SetOriginalTitle(L"Test original window title.");
|
||||
|
||||
const auto originalTitle = gci.GetOriginalTitle();
|
||||
|
||||
int const iBytesNeeded = WideCharToMultiByte(gci.OutputCP,
|
||||
0,
|
||||
gci.GetOriginalTitle().c_str(),
|
||||
-1,
|
||||
originalTitle.data(),
|
||||
gsl::narrow_cast<int>(originalTitle.size()),
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
|
@ -276,8 +283,8 @@ class ApiRoutinesTests
|
|||
|
||||
VERIFY_WIN32_BOOL_SUCCEEDED(WideCharToMultiByte(gci.OutputCP,
|
||||
0,
|
||||
gci.GetOriginalTitle().c_str(),
|
||||
-1,
|
||||
originalTitle.data(),
|
||||
gsl::narrow_cast<int>(originalTitle.size()),
|
||||
pszExpected.get(),
|
||||
iBytesNeeded,
|
||||
nullptr,
|
||||
|
@ -306,10 +313,12 @@ class ApiRoutinesTests
|
|||
VERIFY_SUCCEEDED(_pApiRoutines->GetConsoleOriginalTitleWImpl(gsl::span<wchar_t>(pwszTitle, ARRAYSIZE(pwszTitle)), cchWritten, cchNeeded));
|
||||
|
||||
VERIFY_ARE_NOT_EQUAL(0u, cchWritten);
|
||||
|
||||
const auto originalTitle = gci.GetOriginalTitle();
|
||||
// NOTE: W version of API returns string length. A version of API returns buffer length (string + null).
|
||||
VERIFY_ARE_EQUAL(gci.GetOriginalTitle().length(), cchWritten);
|
||||
VERIFY_ARE_EQUAL(gci.GetOriginalTitle().length(), cchNeeded);
|
||||
VERIFY_ARE_EQUAL(WEX::Common::String(gci.GetOriginalTitle().c_str()), WEX::Common::String(pwszTitle));
|
||||
VERIFY_ARE_EQUAL(originalTitle.length(), cchWritten);
|
||||
VERIFY_ARE_EQUAL(originalTitle.length(), cchNeeded);
|
||||
VERIFY_ARE_EQUAL(WEX::Common::String(originalTitle.data(), gsl::narrow_cast<int>(originalTitle.size())), WEX::Common::String(pwszTitle));
|
||||
}
|
||||
|
||||
static void s_AdjustOutputWait(const bool fShouldBlock)
|
||||
|
|
|
@ -355,9 +355,9 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
const std::wstring GetConsoleTitle() const noexcept override
|
||||
const std::wstring_view GetConsoleTitle() const noexcept override
|
||||
{
|
||||
return std::wstring{};
|
||||
return std::wstring_view{};
|
||||
}
|
||||
|
||||
const bool IsSelectionActive() const override
|
||||
|
|
|
@ -263,7 +263,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
|||
return const_iterator(_bits, _sz, _sz.area());
|
||||
}
|
||||
|
||||
const std::vector<til::rectangle, run_allocator_type>& runs() const
|
||||
const gsl::span<const til::rectangle> runs() const
|
||||
{
|
||||
// If we don't have cached runs, rebuild.
|
||||
if (!_runs.has_value())
|
||||
|
@ -271,7 +271,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
|||
_runs.emplace(begin(), end());
|
||||
}
|
||||
|
||||
// Return a reference to the runs.
|
||||
// Return the runs.
|
||||
return _runs.value();
|
||||
}
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ BgfxEngine::BgfxEngine(PVOID SharedViewBase, LONG DisplayHeight, LONG DisplayWid
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
std::vector<til::rectangle> BgfxEngine::GetDirtyArea()
|
||||
[[nodiscard]] HRESULT BgfxEngine::GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept
|
||||
{
|
||||
SMALL_RECT r;
|
||||
r.Bottom = _displayHeight > 0 ? (SHORT)(_displayHeight - 1) : 0;
|
||||
|
@ -238,7 +238,12 @@ std::vector<til::rectangle> BgfxEngine::GetDirtyArea()
|
|||
r.Left = 0;
|
||||
r.Right = _displayWidth > 0 ? (SHORT)(_displayWidth - 1) : 0;
|
||||
|
||||
return { r };
|
||||
_dirtyArea = r;
|
||||
|
||||
area = { &_dirtyArea,
|
||||
1 };
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT BgfxEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
|
||||
|
@ -260,7 +265,7 @@ std::vector<til::rectangle> BgfxEngine::GetDirtyArea()
|
|||
// - newTitle: the new string to use for the title of the window
|
||||
// Return Value:
|
||||
// - S_OK
|
||||
[[nodiscard]] HRESULT BgfxEngine::_DoUpdateTitle(_In_ const std::wstring& /*newTitle*/) noexcept
|
||||
[[nodiscard]] HRESULT BgfxEngine::_DoUpdateTitle(_In_ const std::wstring_view /*newTitle*/) noexcept
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -67,12 +67,12 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, int const iDpi) noexcept override;
|
||||
|
||||
std::vector<til::rectangle> GetDirtyArea() override;
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring& newTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
private:
|
||||
ULONG_PTR _sharedViewBase;
|
||||
|
@ -80,6 +80,7 @@ namespace Microsoft::Console::Render
|
|||
|
||||
LONG _displayHeight;
|
||||
LONG _displayWidth;
|
||||
til::rectangle _dirtyArea;
|
||||
|
||||
COORD _fontSize;
|
||||
|
||||
|
|
|
@ -289,11 +289,17 @@ void Window::_UpdateSystemMetrics() const
|
|||
}
|
||||
}
|
||||
|
||||
// CreateWindowExW needs a null terminated string, so ensure
|
||||
// title is null terminated in a std::wstring here.
|
||||
// We don't mind the string copy here because making the window
|
||||
// should be infrequent.
|
||||
const std::wstring title{ gci.GetTitle() };
|
||||
|
||||
// Attempt to create window
|
||||
HWND hWnd = CreateWindowExW(
|
||||
CONSOLE_WINDOW_EX_FLAGS,
|
||||
CONSOLE_WINDOW_CLASS,
|
||||
gci.GetTitle().c_str(),
|
||||
title.c_str(),
|
||||
CONSOLE_WINDOW_FLAGS,
|
||||
WI_IsFlagSet(gci.Flags, CONSOLE_AUTO_POSITION) ? CW_USEDEFAULT : rectProposed.left,
|
||||
rectProposed.top, // field is ignored if CW_USEDEFAULT was chosen above
|
||||
|
|
|
@ -687,7 +687,10 @@ using namespace Microsoft::Console::Types;
|
|||
|
||||
case CM_UPDATE_TITLE:
|
||||
{
|
||||
SetWindowTextW(hWnd, gci.GetTitleAndPrefix().c_str());
|
||||
// SetWindowTextW needs null terminated string so assign view to string.
|
||||
const std::wstring titleAndPrefix{ gci.GetTitleAndPrefix() };
|
||||
|
||||
SetWindowTextW(hWnd, titleAndPrefix.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ RenderEngineBase::RenderEngineBase() :
|
|||
{
|
||||
}
|
||||
|
||||
HRESULT RenderEngineBase::InvalidateTitle(const std::wstring& proposedTitle) noexcept
|
||||
HRESULT RenderEngineBase::InvalidateTitle(const std::wstring_view proposedTitle) noexcept
|
||||
{
|
||||
if (proposedTitle != _lastFrameTitle)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ HRESULT RenderEngineBase::InvalidateTitle(const std::wstring& proposedTitle) noe
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderEngineBase::UpdateTitle(const std::wstring& newTitle) noexcept
|
||||
HRESULT RenderEngineBase::UpdateTitle(const std::wstring_view newTitle) noexcept
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
if (newTitle != _lastFrameTitle)
|
||||
|
|
|
@ -467,7 +467,7 @@ void Renderer::TriggerCircling()
|
|||
// - <none>
|
||||
void Renderer::TriggerTitleChange()
|
||||
{
|
||||
const std::wstring newTitle = _pData->GetConsoleTitle();
|
||||
const auto newTitle = _pData->GetConsoleTitle();
|
||||
for (IRenderEngine* const pEngine : _rgpEngines)
|
||||
{
|
||||
LOG_IF_FAILED(pEngine->InvalidateTitle(newTitle));
|
||||
|
@ -483,7 +483,7 @@ void Renderer::TriggerTitleChange()
|
|||
// - the HRESULT of the underlying engine's UpdateTitle call.
|
||||
HRESULT Renderer::_PaintTitle(IRenderEngine* const pEngine)
|
||||
{
|
||||
const std::wstring newTitle = _pData->GetConsoleTitle();
|
||||
const auto newTitle = _pData->GetConsoleTitle();
|
||||
return pEngine->UpdateTitle(newTitle);
|
||||
}
|
||||
|
||||
|
@ -627,9 +627,10 @@ void Renderer::_PaintBufferOutput(_In_ IRenderEngine* const pEngine)
|
|||
|
||||
// This is effectively the number of cells on the visible screen that need to be redrawn.
|
||||
// The origin is always 0, 0 because it represents the screen itself, not the underlying buffer.
|
||||
const auto dirtyAreas = pEngine->GetDirtyArea();
|
||||
gsl::span<const til::rectangle> dirtyAreas;
|
||||
LOG_IF_FAILED(pEngine->GetDirtyArea(dirtyAreas));
|
||||
|
||||
for (const auto dirtyRect : dirtyAreas)
|
||||
for (const auto& dirtyRect : dirtyAreas)
|
||||
{
|
||||
auto dirty = Viewport::FromInclusive(dirtyRect);
|
||||
|
||||
|
@ -1044,7 +1045,10 @@ void Renderer::_PaintOverlay(IRenderEngine& engine,
|
|||
// Set it up in a Viewport helper structure and trim it the IME viewport to be within the full console viewport.
|
||||
Viewport viewConv = Viewport::FromInclusive(srCaView);
|
||||
|
||||
for (SMALL_RECT srDirty : engine.GetDirtyArea())
|
||||
gsl::span<const til::rectangle> dirtyAreas;
|
||||
LOG_IF_FAILED(engine.GetDirtyArea(dirtyAreas));
|
||||
|
||||
for (SMALL_RECT srDirty : dirtyAreas)
|
||||
{
|
||||
// Dirty is an inclusive rectangle, but oddly enough the IME was an exclusive one, so correct it.
|
||||
srDirty.Bottom++;
|
||||
|
@ -1101,13 +1105,14 @@ void Renderer::_PaintSelection(_In_ IRenderEngine* const pEngine)
|
|||
{
|
||||
try
|
||||
{
|
||||
auto dirtyAreas = pEngine->GetDirtyArea();
|
||||
gsl::span<const til::rectangle> dirtyAreas;
|
||||
LOG_IF_FAILED(pEngine->GetDirtyArea(dirtyAreas));
|
||||
|
||||
// Get selection rectangles
|
||||
const auto rectangles = _GetSelectionRects();
|
||||
for (auto rect : rectangles)
|
||||
{
|
||||
for (auto dirtyRect : dirtyAreas)
|
||||
for (auto& dirtyRect : dirtyAreas)
|
||||
{
|
||||
// Make a copy as `TrimToViewport` will manipulate it and
|
||||
// can destroy it for the next dirtyRect to test against.
|
||||
|
|
|
@ -66,7 +66,8 @@ using namespace Microsoft::Console::Types;
|
|||
DxEngine::DxEngine() :
|
||||
RenderEngineBase(),
|
||||
_invalidateFullRows{ true },
|
||||
_invalidMap{},
|
||||
_pool{ til::pmr::get_default_resource() },
|
||||
_invalidMap{ &_pool },
|
||||
_invalidScroll{},
|
||||
_allInvalid{ false },
|
||||
_firstFrame{ true },
|
||||
|
@ -2087,13 +2088,16 @@ float DxEngine::GetScaling() const noexcept
|
|||
// Routine Description:
|
||||
// - Gets the area that we currently believe is dirty within the character cell grid
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// - area - Rectangle describing dirty area in characters.
|
||||
// Return Value:
|
||||
// - Rectangle describing dirty area in characters.
|
||||
[[nodiscard]] std::vector<til::rectangle> DxEngine::GetDirtyArea()
|
||||
// - S_OK
|
||||
[[nodiscard]] HRESULT DxEngine::GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept
|
||||
try
|
||||
{
|
||||
return _invalidMap.runs();
|
||||
area = _invalidMap.runs();
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
|
||||
// Routine Description:
|
||||
// - Gets the current font size
|
||||
|
@ -2141,7 +2145,7 @@ CATCH_RETURN();
|
|||
// - newTitle: the new string to use for the title of the window
|
||||
// Return Value:
|
||||
// - S_OK
|
||||
[[nodiscard]] HRESULT DxEngine::_DoUpdateTitle(_In_ const std::wstring& /*newTitle*/) noexcept
|
||||
[[nodiscard]] HRESULT DxEngine::_DoUpdateTitle(_In_ const std::wstring_view /*newTitle*/) noexcept
|
||||
{
|
||||
if (_hwndTarget != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
|
|
@ -113,7 +113,7 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, int const iDpi) noexcept override;
|
||||
|
||||
[[nodiscard]] std::vector<til::rectangle> GetDirtyArea() override;
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
@ -130,7 +130,7 @@ namespace Microsoft::Console::Render
|
|||
void UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring& newTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring_view newTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT _PaintTerminalEffects() noexcept;
|
||||
[[nodiscard]] bool _FullRepaintNeeded() const noexcept;
|
||||
|
||||
|
@ -181,7 +181,8 @@ namespace Microsoft::Console::Render
|
|||
|
||||
bool _firstFrame;
|
||||
bool _invalidateFullRows;
|
||||
til::bitmap _invalidMap;
|
||||
std::pmr::unsynchronized_pool_resource _pool;
|
||||
til::pmr::bitmap _invalidMap;
|
||||
til::point _invalidScroll;
|
||||
bool _allInvalid;
|
||||
|
||||
|
|
|
@ -66,12 +66,12 @@ namespace Microsoft::Console::Render
|
|||
_Out_ FontInfo& Font,
|
||||
const int iDpi) noexcept override;
|
||||
|
||||
[[nodiscard]] std::vector<til::rectangle> GetDirtyArea() override;
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring& newTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
private:
|
||||
HWND _hwndTargetWindow;
|
||||
|
@ -82,6 +82,7 @@ namespace Microsoft::Console::Render
|
|||
|
||||
bool _fPaintStarted;
|
||||
|
||||
til::rectangle _invalidCharacters;
|
||||
PAINTSTRUCT _psInvalidData;
|
||||
HDC _hdcMemoryContext;
|
||||
bool _isTrueTypeFont;
|
||||
|
|
|
@ -12,18 +12,22 @@ using namespace Microsoft::Console::Render;
|
|||
// Routine Description:
|
||||
// - Gets the size in characters of the current dirty portion of the frame.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The character dimensions of the current dirty area of the frame.
|
||||
// - area - The character dimensions of the current dirty area of the frame.
|
||||
// This is an Inclusive rect.
|
||||
std::vector<til::rectangle> GdiEngine::GetDirtyArea()
|
||||
// Return Value:
|
||||
// - S_OK or math failure
|
||||
[[nodiscard]] HRESULT GdiEngine::GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept
|
||||
{
|
||||
RECT rc = _psInvalidData.rcPaint;
|
||||
|
||||
SMALL_RECT sr = { 0 };
|
||||
LOG_IF_FAILED(_ScaleByFont(&rc, &sr));
|
||||
RETURN_IF_FAILED(_ScaleByFont(&rc, &sr));
|
||||
|
||||
return { sr };
|
||||
_invalidCharacters = sr;
|
||||
|
||||
area = { &_invalidCharacters, 1 };
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
|
|
@ -31,6 +31,7 @@ GdiEngine::GdiEngine() :
|
|||
_lastBg(INVALID_COLOR),
|
||||
_lastFontItalic(false),
|
||||
_fPaintStarted(false),
|
||||
_invalidCharacters{},
|
||||
_hfont(nullptr),
|
||||
_hfontItalic(nullptr),
|
||||
_pool{ til::pmr::get_default_resource() }, // It's important the pool is first so it can be given to the others on construction.
|
||||
|
@ -392,7 +393,7 @@ GdiEngine::~GdiEngine()
|
|||
// - newTitle: the new string to use for the title of the window
|
||||
// Return Value:
|
||||
// - S_OK if PostMessageW succeeded, otherwise E_FAIL
|
||||
[[nodiscard]] HRESULT GdiEngine::_DoUpdateTitle(_In_ const std::wstring& /*newTitle*/) noexcept
|
||||
[[nodiscard]] HRESULT GdiEngine::_DoUpdateTitle(_In_ const std::wstring_view /*newTitle*/) noexcept
|
||||
{
|
||||
// the CM_UPDATE_TITLE handler in windowproc will query the updated title.
|
||||
return PostMessageW(_hwndTargetWindow, CM_UPDATE_TITLE, 0, (LPARAM) nullptr) ? S_OK : E_FAIL;
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace Microsoft::Console::Render
|
|||
virtual const std::vector<RenderOverlay> GetOverlays() const noexcept = 0;
|
||||
|
||||
virtual const bool IsGridLineDrawingAllowed() noexcept = 0;
|
||||
virtual const std::wstring GetConsoleTitle() const noexcept = 0;
|
||||
virtual const std::wstring_view GetConsoleTitle() const noexcept = 0;
|
||||
|
||||
virtual const std::wstring GetHyperlinkUri(uint16_t id) const noexcept = 0;
|
||||
virtual const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept = 0;
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] virtual HRESULT InvalidateAll() noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT InvalidateCircling(_Out_ bool* const pForcePaint) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT InvalidateTitle(const std::wstring& proposedTitle) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT InvalidateTitle(const std::wstring_view proposedTitle) noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT PrepareRenderInfo(const RenderFrameInfo& info) noexcept = 0;
|
||||
|
||||
|
@ -100,10 +100,10 @@ namespace Microsoft::Console::Render
|
|||
_Out_ FontInfo& FontInfo,
|
||||
const int iDpi) noexcept = 0;
|
||||
|
||||
virtual std::vector<til::rectangle> GetDirtyArea() = 0;
|
||||
[[nodiscard]] virtual HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateTitle(const std::wstring& newTitle) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT UpdateTitle(const std::wstring_view newTitle) noexcept = 0;
|
||||
};
|
||||
|
||||
inline Microsoft::Console::Render::IRenderEngine::~IRenderEngine() {}
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace Microsoft::Console::Render
|
|||
RenderEngineBase& operator=(RenderEngineBase&&) = default;
|
||||
|
||||
public:
|
||||
[[nodiscard]] HRESULT InvalidateTitle(const std::wstring& proposedTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT InvalidateTitle(const std::wstring_view proposedTitle) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT UpdateTitle(const std::wstring& newTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT UpdateTitle(const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT PrepareRenderInfo(const RenderFrameInfo& info) noexcept override;
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace Microsoft::Console::Render
|
|||
void WaitUntilCanRender() noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] virtual HRESULT _DoUpdateTitle(const std::wstring& newTitle) noexcept = 0;
|
||||
[[nodiscard]] virtual HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept = 0;
|
||||
|
||||
bool _titleChanged;
|
||||
std::wstring _lastFrameTitle;
|
||||
|
|
|
@ -427,12 +427,16 @@ CATCH_RETURN();
|
|||
// - Gets the area that we currently believe is dirty within the character cell grid
|
||||
// - Not currently used by UiaEngine.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// - area - Rectangle describing dirty area in characters.
|
||||
// Return Value:
|
||||
// - Rectangle describing dirty area in characters.
|
||||
[[nodiscard]] std::vector<til::rectangle> UiaEngine::GetDirtyArea()
|
||||
// - S_OK.
|
||||
[[nodiscard]] HRESULT UiaEngine::GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept
|
||||
{
|
||||
return { Viewport::Empty().ToInclusive() };
|
||||
// Magic static is only valid because any instance of this object has the same behavior.
|
||||
// Use member variable instead if this ever changes.
|
||||
const static til::rectangle empty;
|
||||
area = { &empty, 1 };
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
@ -465,7 +469,7 @@ CATCH_RETURN();
|
|||
// - newTitle: the new string to use for the title of the window
|
||||
// Return Value:
|
||||
// - S_FALSE
|
||||
[[nodiscard]] HRESULT UiaEngine::_DoUpdateTitle(_In_ const std::wstring& /*newTitle*/) noexcept
|
||||
[[nodiscard]] HRESULT UiaEngine::_DoUpdateTitle(_In_ const std::wstring_view /*newTitle*/) noexcept
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
|
|
@ -69,12 +69,12 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, int const iDpi) noexcept override;
|
||||
|
||||
[[nodiscard]] std::vector<til::rectangle> GetDirtyArea() override;
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(const std::wstring& newTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
private:
|
||||
bool _isEnabled;
|
||||
|
|
|
@ -57,7 +57,8 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
|
|||
}
|
||||
else
|
||||
{
|
||||
const auto dirty = GetDirtyArea();
|
||||
gsl::span<const til::rectangle> dirty;
|
||||
RETURN_IF_FAILED(GetDirtyArea(dirty));
|
||||
|
||||
// If we have 0 or 1 dirty pieces in the area, set as appropriate.
|
||||
Viewport dirtyView = dirty.empty() ? Viewport::Empty() : Viewport::FromInclusive(til::at(dirty, 0));
|
||||
|
@ -540,7 +541,7 @@ CATCH_RETURN();
|
|||
// - newTitle: the new string to use for the title of the window
|
||||
// Return Value:
|
||||
// - S_OK
|
||||
[[nodiscard]] HRESULT XtermEngine::_DoUpdateTitle(const std::wstring& newTitle) noexcept
|
||||
[[nodiscard]] HRESULT XtermEngine::_DoUpdateTitle(const std::wstring_view newTitle) noexcept
|
||||
{
|
||||
// inbox telnet uses xterm-ascii as its mode. If we're in ascii mode, don't
|
||||
// do anything, to maintain compatibility.
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT _MoveCursor(const COORD coord) noexcept override;
|
||||
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(const std::wstring& newTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class VtRendererTest;
|
||||
|
|
|
@ -13,13 +13,14 @@ using namespace Microsoft::Console::Types;
|
|||
// Routine Description:
|
||||
// - Gets the size in characters of the current dirty portion of the frame.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// - area - The character dimensions of the current dirty area of the frame.
|
||||
// This is an Inclusive rect.
|
||||
// Return Value:
|
||||
// - The character dimensions of the current dirty area of the frame.
|
||||
// This is an Inclusive rect.
|
||||
std::vector<til::rectangle> VtEngine::GetDirtyArea()
|
||||
// - S_OK.
|
||||
[[nodiscard]] HRESULT VtEngine::GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept
|
||||
{
|
||||
return _invalidMap.runs();
|
||||
area = _invalidMap.runs();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
|
|
@ -598,7 +598,7 @@ using namespace Microsoft::Console::Types;
|
|||
// - newTitle: the new string to use for the title of the window
|
||||
// Return Value:
|
||||
// - S_OK
|
||||
[[nodiscard]] HRESULT VtEngine::_DoUpdateTitle(const std::wstring& /*newTitle*/) noexcept
|
||||
[[nodiscard]] HRESULT VtEngine::_DoUpdateTitle(const std::wstring_view /*newTitle*/) noexcept
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,8 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe,
|
|||
_hFile(std::move(pipe)),
|
||||
_lastTextAttributes(INVALID_COLOR, INVALID_COLOR),
|
||||
_lastViewport(initialViewport),
|
||||
_invalidMap(initialViewport.Dimensions()),
|
||||
_pool(til::pmr::get_default_resource()),
|
||||
_invalidMap(initialViewport.Dimensions(), false, &_pool),
|
||||
_lastText({ 0 }),
|
||||
_scrollDelta({ 0, 0 }),
|
||||
_quickReturn(false),
|
||||
|
@ -50,7 +51,10 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe,
|
|||
_deferredCursorPos{ INVALID_COORDS },
|
||||
_inResizeRequest{ false },
|
||||
_trace{},
|
||||
_bufferLine{}
|
||||
_bufferLine{},
|
||||
_buffer{},
|
||||
_formatBuffer{},
|
||||
_conversionBuffer{}
|
||||
{
|
||||
#ifndef UNIT_TESTING
|
||||
// When unit testing, we can instantiate a VtEngine without a pipe.
|
||||
|
@ -144,12 +148,8 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe,
|
|||
// - S_OK or suitable HRESULT error from either conversion or writing pipe.
|
||||
[[nodiscard]] HRESULT VtEngine::_WriteTerminalUtf8(const std::wstring_view wstr) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto converted = ConvertToA(CP_UTF8, wstr);
|
||||
return _Write(converted);
|
||||
}
|
||||
CATCH_RETURN();
|
||||
RETURN_IF_FAILED(til::u16u8(wstr, _conversionBuffer));
|
||||
return _Write(_conversionBuffer);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -145,7 +145,7 @@ void RenderTracing::TraceInvalidateScroll(const til::point scroll) const
|
|||
}
|
||||
|
||||
void RenderTracing::TraceStartPaint(const bool quickReturn,
|
||||
const til::bitmap& invalidMap,
|
||||
const til::pmr::bitmap& invalidMap,
|
||||
const til::rectangle lastViewport,
|
||||
const til::point scrollDelt,
|
||||
const bool cursorMoved,
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace Microsoft::Console::VirtualTerminal
|
|||
void TraceTriggerCircling(const bool newFrame) const;
|
||||
void TraceInvalidateScroll(const til::point scroll) const;
|
||||
void TraceStartPaint(const bool quickReturn,
|
||||
const til::bitmap& invalidMap,
|
||||
const til::pmr::bitmap& invalidMap,
|
||||
const til::rectangle lastViewport,
|
||||
const til::point scrollDelta,
|
||||
const bool cursorMoved,
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace Microsoft::Console::Render
|
|||
_Out_ FontInfo& Font,
|
||||
const int iDpi) noexcept override;
|
||||
|
||||
std::vector<til::rectangle> GetDirtyArea() override;
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
|
@ -113,12 +113,14 @@ namespace Microsoft::Console::Render
|
|||
std::string _buffer;
|
||||
|
||||
std::string _formatBuffer;
|
||||
std::string _conversionBuffer;
|
||||
|
||||
TextAttribute _lastTextAttributes;
|
||||
|
||||
Microsoft::Console::Types::Viewport _lastViewport;
|
||||
|
||||
til::bitmap _invalidMap;
|
||||
std::pmr::unsynchronized_pool_resource _pool;
|
||||
til::pmr::bitmap _invalidMap;
|
||||
|
||||
COORD _lastText;
|
||||
til::point _scrollDelta;
|
||||
|
@ -222,7 +224,7 @@ namespace Microsoft::Console::Render
|
|||
[[nodiscard]] HRESULT _WriteTerminalUtf8(const std::wstring_view str) noexcept;
|
||||
[[nodiscard]] HRESULT _WriteTerminalAscii(const std::wstring_view str) noexcept;
|
||||
|
||||
[[nodiscard]] virtual HRESULT _DoUpdateTitle(const std::wstring& newTitle) noexcept override;
|
||||
[[nodiscard]] virtual HRESULT _DoUpdateTitle(const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
/////////////////////////// Unit Testing Helpers ///////////////////////////
|
||||
#ifdef UNIT_TESTING
|
||||
|
|
|
@ -353,7 +353,7 @@ bool WddmConEngine::IsInitialized()
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
std::vector<til::rectangle> WddmConEngine::GetDirtyArea()
|
||||
[[nodiscard]] HRESULT WddmConEngine::GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept
|
||||
{
|
||||
SMALL_RECT r;
|
||||
r.Bottom = _displayHeight > 0 ? (SHORT)(_displayHeight - 1) : 0;
|
||||
|
@ -361,7 +361,12 @@ std::vector<til::rectangle> WddmConEngine::GetDirtyArea()
|
|||
r.Left = 0;
|
||||
r.Right = _displayWidth > 0 ? (SHORT)(_displayWidth - 1) : 0;
|
||||
|
||||
return { r };
|
||||
_dirtyArea = r;
|
||||
|
||||
area = { &_dirtyArea,
|
||||
1 };
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RECT WddmConEngine::GetDisplaySize()
|
||||
|
@ -409,7 +414,7 @@ RECT WddmConEngine::GetDisplaySize()
|
|||
// - newTitle: the new string to use for the title of the window
|
||||
// Return Value:
|
||||
// - S_OK
|
||||
[[nodiscard]] HRESULT WddmConEngine::_DoUpdateTitle(_In_ const std::wstring& /*newTitle*/) noexcept
|
||||
[[nodiscard]] HRESULT WddmConEngine::_DoUpdateTitle(_In_ const std::wstring_view /*newTitle*/) noexcept
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -59,12 +59,12 @@ namespace Microsoft::Console::Render
|
|||
|
||||
[[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, int const iDpi) noexcept override;
|
||||
|
||||
std::vector<til::rectangle> GetDirtyArea() override;
|
||||
[[nodiscard]] HRESULT GetDirtyArea(gsl::span<const til::rectangle>& area) noexcept override;
|
||||
[[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override;
|
||||
[[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring& newTitle) noexcept override;
|
||||
[[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring_view newTitle) noexcept override;
|
||||
|
||||
private:
|
||||
HANDLE _hWddmConCtx;
|
||||
|
@ -75,6 +75,7 @@ namespace Microsoft::Console::Render
|
|||
// Variables
|
||||
LONG _displayHeight;
|
||||
LONG _displayWidth;
|
||||
til::rectangle _dirtyArea;
|
||||
|
||||
PCD_IO_ROW_INFORMATION* _displayState;
|
||||
|
||||
|
|
Loading…
Reference in a new issue