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

Defer text buffer redrawing #3089

Closed
Closed
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
4 changes: 4 additions & 0 deletions src/buffer/out/textBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
// Get size of the text buffer so we can stay in bounds.
const auto size = GetSize();

_renderTarget.StartDeferRedrawing();

// While there's still data in the iterator and we're still targeting in bounds...
while (it && size.IsInBounds(lineTarget))
{
Expand All @@ -346,6 +348,8 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
++lineTarget.Y;
}

_renderTarget.EndDeferRedrawing();

return it;
}

Expand Down
19 changes: 19 additions & 0 deletions src/host/ScreenBufferRenderTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ ScreenBufferRenderTarget::ScreenBufferRenderTarget(SCREEN_INFORMATION& owner) :
{
}

void ScreenBufferRenderTarget::StartDeferRedrawing()
{
auto* pRenderer = ServiceLocator::LocateGlobals().pRender;
const auto* pActive = &ServiceLocator::LocateGlobals().getConsoleInformation().GetActiveOutputBuffer().GetActiveBuffer();
if (pRenderer != nullptr && pActive == &_owner)
{
pRenderer->StartDeferRedrawing();
}
}
void ScreenBufferRenderTarget::EndDeferRedrawing()
{
auto* pRenderer = ServiceLocator::LocateGlobals().pRender;
const auto* pActive = &ServiceLocator::LocateGlobals().getConsoleInformation().GetActiveOutputBuffer().GetActiveBuffer();
if (pRenderer != nullptr && pActive == &_owner)
{
pRenderer->EndDeferRedrawing();
}
}

void ScreenBufferRenderTarget::TriggerRedraw(const Microsoft::Console::Types::Viewport& region)
{
auto* pRenderer = ServiceLocator::LocateGlobals().pRender;
Expand Down
2 changes: 2 additions & 0 deletions src/host/ScreenBufferRenderTarget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class ScreenBufferRenderTarget final : public Microsoft::Console::Render::IRende
public:
ScreenBufferRenderTarget(SCREEN_INFORMATION& owner);

void StartDeferRedrawing();
void EndDeferRedrawing();
void TriggerRedraw(const Microsoft::Console::Types::Viewport& region) override;
void TriggerRedraw(const COORD* const pcoord) override;
void TriggerRedrawCursor(const COORD* const pcoord) override;
Expand Down
19 changes: 19 additions & 0 deletions src/renderer/base/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ Renderer::~Renderer()

[[nodiscard]] HRESULT Renderer::_PaintFrameForEngine(_In_ IRenderEngine* const pEngine)
{
if (_redrawingDefered)
{
return S_OK;
}

FAIL_FAST_IF_NULL(pEngine); // This is a programming error. Fail fast.

_pData->LockConsole();
Expand Down Expand Up @@ -151,10 +156,24 @@ Renderer::~Renderer()

void Renderer::_NotifyPaintFrame()
{
if (_redrawingDefered)
{
return;
}
// The thread will provide throttling for us.
_pThread->NotifyPaint();
}

void Renderer::StartDeferRedrawing()
{
_redrawingDefered = true;
}

void Renderer::EndDeferRedrawing()
{
_redrawingDefered = false;
}

// Routine Description:
// - Called when the system has requested we redraw a portion of the console.
// Arguments:
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/base/renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ namespace Microsoft::Console::Render

[[nodiscard]] HRESULT PaintFrame();

void StartDeferRedrawing();
void EndDeferRedrawing();
void TriggerSystemRedraw(const RECT* const prcDirtyClient) override;
void TriggerRedraw(const Microsoft::Console::Types::Viewport& region) override;
void TriggerRedraw(const COORD* const pcoord) override;
Expand Down Expand Up @@ -125,5 +127,7 @@ namespace Microsoft::Console::Render
// Helper functions to diagnose issues with painting and layout.
// These are only actually effective/on in Debug builds when the flag is set using an attached debugger.
bool _fDebug = false;

bool _redrawingDefered = false;
};
}
2 changes: 2 additions & 0 deletions src/renderer/inc/IRenderTarget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ namespace Microsoft::Console::Render
IRenderTarget& operator=(IRenderTarget&&) = default;

public:
virtual void StartDeferRedrawing() = 0;
virtual void EndDeferRedrawing() = 0;
virtual void TriggerRedraw(const Microsoft::Console::Types::Viewport& region) = 0;
virtual void TriggerRedraw(const COORD* const pcoord) = 0;
virtual void TriggerRedrawCursor(const COORD* const pcoord) = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/inc/IRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ namespace Microsoft::Console::Render

[[nodiscard]] virtual HRESULT PaintFrame() = 0;

virtual void StartDeferRedrawing() = 0;
virtual void EndDeferRedrawing() = 0;

virtual void TriggerSystemRedraw(const RECT* const prcDirtyClient) = 0;

virtual void TriggerRedraw(const Microsoft::Console::Types::Viewport& region) = 0;
Expand Down