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

Prevent the VT engine painting unnecessarily #17194

Merged
merged 1 commit into from
May 6, 2024
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
20 changes: 10 additions & 10 deletions src/renderer/vt/XtermEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,16 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
// the pipe.
[[nodiscard]] HRESULT XtermEngine::StartPaint() noexcept
{
RETURN_IF_FAILED(VtEngine::StartPaint());
const auto hr = VtEngine::StartPaint();
if (hr != S_OK)
{
// If _noFlushOnEnd was set, and we didn't return early, it would usually
// have been reset in the EndPaint call. But since that's not going to
// happen now, we need to reset it here, otherwise we may mistakenly skip
// the flush on the next frame.
_noFlushOnEnd = false;
return hr;
}

_trace.TraceLastText(_lastText);

Expand Down Expand Up @@ -83,15 +92,6 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe,
}
}

if (!_quickReturn)
{
if (_WillWriteSingleChar())
{
// Don't re-enable the cursor.
_quickReturn = true;
}
}

return S_OK;
}

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/vt/invalidate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ CATCH_RETURN();
}
_skipCursor = false;

_cursorMoved = true;
_cursorMoved = psrRegion->origin() != _lastText;
return S_OK;
}

Expand Down
35 changes: 0 additions & 35 deletions src/renderer/vt/math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,3 @@ void VtEngine::_OrRect(_Inout_ til::inclusive_rect* const pRectExisting, const t
pRectExisting->right = std::max(pRectExisting->right, pRectToOr->right);
pRectExisting->bottom = std::max(pRectExisting->bottom, pRectToOr->bottom);
}

// Method Description:
// - Returns true if the invalidated region indicates that we only need to
// simply print text from the current cursor position. This will prevent us
// from sending extra VT set-up/tear down sequences (?12h/l) when all we
// need to do is print more text at the current cursor position.
// Arguments:
// - <none>
// Return Value:
// - true iff only the next character is invalid
bool VtEngine::_WillWriteSingleChar() const
{
// If there is no scroll delta, return false.
if (til::point{ 0, 0 } != _scrollDelta)
{
return false;
}

// If there is more than one invalid char, return false.
if (!_invalidMap.one())
{
return false;
}

// Get the single point at which things are invalid.
const auto invalidPoint = _invalidMap.runs().front().origin();

// Either the next character to the right or the immediately previous
// character should follow this code path
// (The immediate previous character would suggest a backspace)
auto invalidIsNext = invalidPoint == _lastText;
auto invalidIsLast = invalidPoint == til::point{ _lastText.x - 1, _lastText.y };

return invalidIsNext || invalidIsLast;
}
16 changes: 8 additions & 8 deletions src/renderer/vt/paint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,30 @@ using namespace Microsoft::Console::Types;
// HRESULT error code if painting didn't start successfully.
[[nodiscard]] HRESULT VtEngine::StartPaint() noexcept
{
// When unit testing, there may be no pipe, but we still need to paint.
if (!_hFile)
{
return S_FALSE;
return S_OK;
}

// If we're using line renditions, and this is a full screen paint, we can
// potentially stop using them at the end of this frame.
_stopUsingLineRenditions = _usingLineRenditions && _AllIsInvalid();

// If there's nothing to do, quick return
// If there's nothing to do, we won't need to paint.
auto somethingToDo = _invalidMap.any() ||
_scrollDelta != til::point{ 0, 0 } ||
_cursorMoved ||
_titleChanged;

_quickReturn = !somethingToDo;
_trace.TraceStartPaint(_quickReturn,
_trace.TraceStartPaint(!somethingToDo,
_invalidMap,
_lastViewport.ToExclusive(),
_scrollDelta,
_cursorMoved,
_wrappedRow);

return _quickReturn ? S_FALSE : S_OK;
return somethingToDo ? S_OK : S_FALSE;
}

// Routine Description:
Expand Down Expand Up @@ -142,9 +142,9 @@ using namespace Microsoft::Console::Types;
_usingLineRenditions = true;
}
// One simple optimization is that we can skip sending the line attributes
// when _quickReturn is true. That indicates that we're writing out a single
// character, which should preclude there being a rendition switch.
if (_usingLineRenditions && !_quickReturn)
// when we're writing out a single character, which should preclude there
// being a rendition switch.
if (_usingLineRenditions && !_invalidMap.one())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if .one() returns true for a single invalid wide char, but on the other hand... meh?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this was very much a "meh" solution, even more so when it was using quickReturn. I just wanted something that was easy to test, and not risk false positives by overcomplicating it. Most people will never be impacted by this anyway.

{
RETURN_IF_FAILED(_MoveCursor({ _lastText.x, targetRow }));
switch (lineRendition)
Expand Down
1 change: 0 additions & 1 deletion src/renderer/vt/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe,
_pool(til::pmr::get_default_resource()),
_invalidMap(initialViewport.Dimensions(), false, &_pool),
_scrollDelta(0, 0),
_quickReturn(false),
_clearedAllThisFrame(false),
_cursorMoved(false),
_resized(false),
Expand Down
3 changes: 0 additions & 3 deletions src/renderer/vt/vtrenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ namespace Microsoft::Console::Render
til::point _lastText;
til::point _scrollDelta;

bool _quickReturn;
bool _clearedAllThisFrame;
bool _cursorMoved;
bool _resized;
Expand Down Expand Up @@ -214,8 +213,6 @@ namespace Microsoft::Console::Render
[[nodiscard]] HRESULT _RgbUpdateDrawingBrushes(const TextAttribute& textAttributes) noexcept;
[[nodiscard]] HRESULT _16ColorUpdateDrawingBrushes(const TextAttribute& textAttributes) noexcept;

bool _WillWriteSingleChar() const;

// buffer space for these two functions to build their lines
// so they don't have to alloc/free in a tight loop
std::wstring _bufferLine;
Expand Down
Loading