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

Eliminate more transient allocations: Titles and invalid rectangles and bitmap runs and utf8 conversions #8621

Merged
23 commits merged into from
Feb 16, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
60bbf49
We never look at just the prefix. So store Title+Prefix concatenated …
miniksa Dec 19, 2020
be5da8d
Finish fixing title. Change all Dirty Areas to be stored in the engin…
miniksa Dec 19, 2020
f66d51e
Make it use wstring_view
miniksa Jan 7, 2021
2983b9d
These should be string views to match.
miniksa Jan 7, 2021
b2e6d6d
Code format!
miniksa Jan 7, 2021
50e8ee8
static analysis
miniksa Jan 7, 2021
141bbd9
fix test things too.
miniksa Jan 7, 2021
ead8fab
Merge branch 'main' into dev/miniksa/perf_title_and_dirty
miniksa Jan 7, 2021
00f80e4
Add held-buffer converter helpers for hot paths.
miniksa Jan 8, 2021
d8cbaed
Hold a conversion buffer string on the VtEngine to prevent hundreds o…
miniksa Jan 8, 2021
1882623
use PMR pool for the vector in the bitmap so we're not alloc/freeing …
miniksa Jan 8, 2021
f378785
Revert "Hold a conversion buffer string on the VtEngine to prevent hu…
miniksa Jan 8, 2021
0f4d33b
Use u16u8 instead of reinventing the wheel on out parameters for conv…
miniksa Jan 8, 2021
1d977b7
code format!'
miniksa Jan 8, 2021
8221b22
Validated in razzle. Forgot to declare the rectangle in bgfx engine.
miniksa Jan 8, 2021
9fefabf
Spell check. codepath --> code path.
miniksa Jan 8, 2021
fa1e14a
missed a noexcept for audit mode.
miniksa Jan 15, 2021
ebbda64
Don't bother adding these functions to Convert since I didn't use 'em…
miniksa Jan 15, 2021
1929b32
Fixed it I think.
miniksa Jan 20, 2021
7662ea8
Merge branch 'main' into dev/miniksa/perf_title_and_dirty
miniksa Feb 12, 2021
c6432ae
ensure that PMR is being used now that it's not strictly a part of th…
miniksa Feb 12, 2021
a6f1b49
Reorder constructors for bitmap how they are in main. Use the three-p…
miniksa Feb 13, 2021
b308974
CODE FORMAT!!!!
miniksa Feb 16, 2021
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
6 changes: 3 additions & 3 deletions src/host/consoleInformation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ void CONSOLE_INFORMATION::SetTitle(const std::wstring_view newTitle)
// - <none>
void CONSOLE_INFORMATION::SetTitlePrefix(const std::wstring& newTitlePrefix)
{
_TitlePrefix = newTitlePrefix;
_TitleAndPrefix = newTitlePrefix + _Title;

auto* const pRender = ServiceLocator::LocateGlobals().pRender;
if (pRender)
Expand Down Expand Up @@ -337,9 +337,9 @@ const std::wstring& CONSOLE_INFORMATION::GetTitle() const noexcept
// - <none>
// Return Value:
// - a new wstring containing the combined prefix and title.
const std::wstring CONSOLE_INFORMATION::GetTitleAndPrefix() const
const std::wstring& CONSOLE_INFORMATION::GetTitleAndPrefix() const
miniksa marked this conversation as resolved.
Show resolved Hide resolved
{
return _TitlePrefix + _Title;
return _TitleAndPrefix;
}

// Method Description:
Expand Down
2 changes: 1 addition & 1 deletion src/host/renderData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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& RenderData::GetConsoleTitle() const noexcept
{
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
return gci.GetTitleAndPrefix();
Expand Down
2 changes: 1 addition & 1 deletion src/host/renderData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class RenderData final :

const bool IsGridLineDrawingAllowed() noexcept override;

const std::wstring GetConsoleTitle() const noexcept override;
const std::wstring& GetConsoleTitle() const noexcept override;

const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
Expand Down
4 changes: 2 additions & 2 deletions src/host/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class CONSOLE_INFORMATION :
const std::wstring& GetTitle() const noexcept;
const std::wstring& GetOriginalTitle() const noexcept;
const std::wstring& GetLinkTitle() const noexcept;
const std::wstring GetTitleAndPrefix() const;
const std::wstring& GetTitleAndPrefix() const;

[[nodiscard]] static NTSTATUS AllocateConsole(const std::wstring_view title);
// MSFT:16886775 : get rid of friends
Expand All @@ -152,7 +152,7 @@ class CONSOLE_INFORMATION :
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 _TitleAndPrefix; // Eg Select, Mark - things that we manually prepend to the title.
std::wstring _OriginalTitle;
std::wstring _LinkTitle; // Path to .lnk file
SCREEN_INFORMATION* pCurrentScreenBuffer;
Expand Down
10 changes: 8 additions & 2 deletions src/interactivity/onecore/BgfxEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,21 @@ 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
miniksa marked this conversation as resolved.
Show resolved Hide resolved
{

SMALL_RECT r;
r.Bottom = _displayHeight > 0 ? (SHORT)(_displayHeight - 1) : 0;
r.Top = 0;
r.Left = 0;
r.Right = _displayWidth > 0 ? (SHORT)(_displayWidth - 1) : 0;

return { r };
_dirtyArea = r;

_area = { &_dirtyArea,
miniksa marked this conversation as resolved.
Show resolved Hide resolved
miniksa marked this conversation as resolved.
Show resolved Hide resolved
1 };

return S_OK;
}

[[nodiscard]] HRESULT BgfxEngine::GetFontSize(_Out_ COORD* const pFontSize) noexcept
Expand Down
2 changes: 1 addition & 1 deletion src/interactivity/onecore/BgfxEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ 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;

Expand Down
19 changes: 12 additions & 7 deletions src/renderer/base/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,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));
Expand All @@ -475,7 +475,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);
}

Expand Down Expand Up @@ -619,9 +619,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);

Expand Down Expand Up @@ -1036,7 +1037,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));
miniksa marked this conversation as resolved.
Show resolved Hide resolved

for (SMALL_RECT srDirty : dirtyAreas)
miniksa marked this conversation as resolved.
Show resolved Hide resolved
{
// Dirty is an inclusive rectangle, but oddly enough the IME was an exclusive one, so correct it.
srDirty.Bottom++;
Expand Down Expand Up @@ -1093,13 +1097,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.
Expand Down
9 changes: 5 additions & 4 deletions src/renderer/dx/DxRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2064,12 +2064,13 @@ 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
{
return _invalidMap.runs();
area = _invalidMap.runs();
return S_OK;
}

// Routine Description:
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/dx/DxRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,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;
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/gdi/gdirenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ 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;

Expand All @@ -82,6 +82,7 @@ namespace Microsoft::Console::Render

bool _fPaintStarted;

til::rectangle _invalidCharacters;
PAINTSTRUCT _psInvalidData;
HDC _hdcMemoryContext;
bool _isTrueTypeFont;
Expand Down
16 changes: 10 additions & 6 deletions src/renderer/gdi/math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions src/renderer/gdi/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ GdiEngine::GdiEngine() :
_lastBg(INVALID_COLOR),
_lastFontItalic(false),
_fPaintStarted(false),
_invalidCharacters{},
_hfont(nullptr),
_hfontItalic(nullptr)
{
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/inc/IRenderData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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& 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;
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/inc/IRenderEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ 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;
Expand Down
13 changes: 9 additions & 4 deletions src/renderer/uia/UiaRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,17 @@ 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 emptyInclusive{ Viewport::Empty().ToInclusive() };
area = { &emptyInclusive,
1 };
return S_OK;
}

// Routine Description:
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/uia/UiaRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,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;

Expand Down
3 changes: 2 additions & 1 deletion src/renderer/vt/XtermEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
11 changes: 6 additions & 5 deletions src/renderer/vt/math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/vt/vtrenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
9 changes: 7 additions & 2 deletions src/renderer/wddmcon/WddmConRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,15 +353,20 @@ 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;
r.Top = 0;
r.Left = 0;
r.Right = _displayWidth > 0 ? (SHORT)(_displayWidth - 1) : 0;

return { r };
_dirtyArea = r;

_area = { &_dirtyArea,
miniksa marked this conversation as resolved.
Show resolved Hide resolved
1 };

return S_OK;
}

RECT WddmConEngine::GetDisplaySize()
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/wddmcon/WddmConRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ 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;

Expand All @@ -75,6 +75,7 @@ namespace Microsoft::Console::Render
// Variables
LONG _displayHeight;
LONG _displayWidth;
til::rectangle _dirtyArea;

PCD_IO_ROW_INFORMATION* _displayState;

Expand Down