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

Fix missing call to UpdateViewport::UpdateViewport during tearout #15175

Merged

Conversation

lhecker
Copy link
Member

@lhecker lhecker commented Apr 13, 2023

This bug causes AtlasEngine to render buffer contents with an incorrect
cellCount, which may either cause it to draw the contents only
partially, or potentially access the TextBuffer contents out of bounds.

EnablePainting sets the _viewport to the current viewport for some
unfortunate (and quite buggy/incorrect) caching purposes, which causes
_CheckViewportAndScroll() to think that the viewport hasn't changed
in the new window. We can ensure _CheckViewportAndScroll() works
by also setting _forceUpdateViewport to true.

Part of #14957

PR Checklist

  • Tear out a tab from a smaller window to a larger window
  • Renderer contents adept to the larger window size ✅

@lhecker lhecker added Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Issue-Bug It either shouldn't be doing this or needs an investigation. Product-Terminal The new Windows Terminal. Priority-1 A description (P1) labels Apr 13, 2023
@@ -638,6 +638,7 @@ void Renderer::EnablePainting()
// When the renderer is constructed, the initial viewport won't be available yet,
// but once EnablePainting is called it should be safe to retrieve.
_viewport = _pData->GetViewport();
_forceUpdateViewport = true;
Copy link
Member Author

@lhecker lhecker Apr 13, 2023

Choose a reason for hiding this comment

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

(silmarillion) moving a tab to a larger window doesn't resize the control - THIS WAS AN ATLAS BUG

So, as it turns out, it's actually a DxRenderer bug which just happens to mask the other bug in Renderer, fixed here. 😄

DxRenderer doesn't use the IRenderEngine::UpdateViewport function. UpdateViewport was probably intended originally to tell the renderer the size of the text buffer.
It just happens to not cause any harm to Windows Terminal specifically, because it calls IRenderEngine::SetWindowSize and Terminal::UserResize while holding the console lock across both calls. So the renderer size and text buffer size always stay in sync. This isn't true for conhost though which uses an asynchronous approach to window resizing: The text buffer is resized on the window message thread, while the renderer thread is "free running" and only gets the current window size when it decides to paint. But by that point the window size might be different from the text buffer size.
This causes DxRenderer to crash with a SIGSEGV when you resize the OpenConsole window too quickly.

src/cascadia/TerminalControl/ControlCore.cpp Show resolved Hide resolved
@@ -131,7 +131,7 @@ namespace Microsoft::Console::Render
std::function<void()> _pfnFrameColorChanged;
std::function<void()> _pfnRendererEnteredErrorState;
bool _destructing = false;
bool _forceUpdateViewport = true;
bool _forceUpdateViewport = false;
Copy link
Member

Choose a reason for hiding this comment

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

this also scares me, since it impacts GDI and WDDM and BGFX!

Copy link
Member Author

Choose a reason for hiding this comment

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

It’s more correct however since the only reason this member exists is because EnablePainting overwrites _viewport which it absolutely should not do. There’s no guarantee that the IRenderData has a valid viewport at that point. Because it overwrites _viewport we need this Boolean to ensure UpdateViewport is called anyways. So in a sense this is more correct because it puts the overwrite to where the mistake is happening in the first place.

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

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

so mad that this didn't submit earlier

src/cascadia/TerminalControl/ControlCore.cpp Show resolved Hide resolved
@zadjii-msft
Copy link
Member

Gonna check this out locally and test it, but yea I'm curious how not needing to re-enable painting is just... fine

@zadjii-msft
Copy link
Member

Mmmmmm. it's probably cause of

image image

@zadjii-msft zadjii-msft added the AutoMerge Marked for automatic merge by the bot when requirements are met label Apr 14, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot enabled auto-merge (squash) April 14, 2023 18:52
DHowett added a commit that referenced this pull request Apr 14, 2023
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
@microsoft-github-policy-service microsoft-github-policy-service bot deleted the dev/lhecker/14957-fix-resize-glitch branch April 25, 2023 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants