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

Teach the renderer to keep thread alive if engine requests it #9091

Merged
merged 4 commits into from
Feb 10, 2021
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
10 changes: 10 additions & 0 deletions src/renderer/base/RenderEngineBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ HRESULT RenderEngineBase::PrepareRenderInfo(const RenderFrameInfo& /*info*/) noe
return S_FALSE;
}

// Method Description:
// - By default, no one should need continuous redraw. It ruins performance
// in terms of CPU, memory, and battery life to just paint forever.
// That's why we sleep when there's nothing to draw.
// But if you REALLY WANT to do special effects... you need to keep painting.
[[nodiscard]] bool RenderEngineBase::RequiresContinuousRedraw() noexcept
{
return false;
}

// Method Description:
// - Blocks until the engine is able to render without blocking.
void RenderEngineBase::WaitUntilCanRender() noexcept
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/base/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ try

auto endPaint = wil::scope_exit([&]() {
LOG_IF_FAILED(pEngine->EndPaint());

// If the engine tells us it really wants to redraw immediately,
// tell the thread so it doesn't go to sleep and ticks again
// at the next opportunity.
if (pEngine->RequiresContinuousRedraw())
Copy link
Member

Choose a reason for hiding this comment

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

oh my gosh this is so clever, I love it

{
_NotifyPaintFrame();
}
});

// A. Prep Colors
Expand Down
22 changes: 22 additions & 0 deletions src/renderer/dx/DxRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,28 @@ CATCH_RETURN()
return S_OK;
}

// Method Description:
// - When the shaders are on, say that we need to keep redrawing every
// possible frame in case they have some smooth action on every frame tick.
// It is presumed that if you're using shaders, you're not about performance...
// You're instead about OOH SHINY. And that's OK. But returning true here is 100%
// a perf detriment.
[[nodiscard]] bool DxEngine::RequiresContinuousRedraw() noexcept
{
// We're only going to request continuous redraw if someone is using
// a pixel shader from a path because we cannot tell if those are using the
// time parameter or not.
// And if they are using time, they probably need it to tick continuously.
//
// By contrast, the in-built retro effect does NOT need it,
// so let's not tick for it and save some amount of performance.
//
// Finally... if we're not using effects at all... let the render thread
// go to sleep. It deserves it. That thread works hard. Also it sleeping
// saves battery power and all sorts of related perf things.
return _terminalEffectsEnabled && !_pixelShaderPath.empty();
}

// Method Description:
// - Blocks until the engine is able to render without blocking.
// - See https://docs.microsoft.com/en-us/windows/uwp/gaming/reduce-latency-with-dxgi-1-3-swap-chains.
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/dx/DxRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ namespace Microsoft::Console::Render
[[nodiscard]] HRESULT StartPaint() noexcept override;
[[nodiscard]] HRESULT EndPaint() noexcept override;

[[nodiscard]] bool RequiresContinuousRedraw() noexcept override;

void WaitUntilCanRender() noexcept override;
[[nodiscard]] HRESULT Present() noexcept override;

Expand Down
1 change: 1 addition & 0 deletions src/renderer/inc/IRenderEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace Microsoft::Console::Render
[[nodiscard]] virtual HRESULT StartPaint() noexcept = 0;
[[nodiscard]] virtual HRESULT EndPaint() noexcept = 0;

[[nodiscard]] virtual bool RequiresContinuousRedraw() noexcept = 0;
virtual void WaitUntilCanRender() noexcept = 0;
[[nodiscard]] virtual HRESULT Present() noexcept = 0;

Expand Down
2 changes: 2 additions & 0 deletions src/renderer/inc/RenderEngineBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace Microsoft::Console::Render

[[nodiscard]] HRESULT PrepareRenderInfo(const RenderFrameInfo& info) noexcept override;

[[nodiscard]] virtual bool RequiresContinuousRedraw() noexcept override;

void WaitUntilCanRender() noexcept override;

protected:
Expand Down