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 conhost UseDx mode #10770

Merged
merged 1 commit into from
Jul 23, 2021
Merged

Fix conhost UseDx mode #10770

merged 1 commit into from
Jul 23, 2021

Conversation

lhecker
Copy link
Member

@lhecker lhecker commented Jul 23, 2021

This commit fixes the UseDx mode for conhost.
In order to add support for UseDx without calling SetWindowSize,
responsibility for resizing _invalidMap has been moved to occur
only when the renderer itself recognizes a new size. Furthermore
InvalidateAll is now the central point to invalidate _invalidMap.

Validation Steps Performed

  • Enabling UseDx enables the DxEngine for conhost ✔️
  • Resizing windows in conhost works ✔️
  • Resizing windows in WT works ✔️

Closes #5455

@lhecker lhecker requested a review from miniksa July 23, 2021 15:49
@ghost ghost added Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) Product-Conhost For issues in the Console codebase labels Jul 23, 2021
Comment on lines +1050 to +1053
const auto size = _invalidMap.size();
const auto topLeft = til::point{ 0, std::min(size.height(), rc.top()) };
const auto bottomRight = til::point{ size.width(), std::min(size.height(), rc.bottom()) };
_invalidMap.set({ topLeft, bottomRight });
Copy link
Member Author

Choose a reason for hiding this comment

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

Due to the missing std::min, but the delayed _invalidMap resize, this was blowing up with exceptions. Now it isn't anymore.

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.

Open question about the divergence between the description and the implementation?

@@ -1322,8 +1318,8 @@ try
// And persist the new size.
_displaySizePixels = clientSize;

// Mark this as the first frame on the new target. We can't use incremental drawing on the first frame.
_firstFrame = true;
_invalidMap.resize(clientSize / _fontRenderData->GlyphCell());
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 confused -- the body of the PR says "responsibility for resizing _invalidMap has been moved entirely into InvalidateAll", but both places we have InvalidateAll calls we resize the map before calling it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Woops I mixed things up. I'm fixing my PR body to say that responsibility for full invalidation was moved there.

Comment on lines +1051 to +1052
const auto topLeft = til::point{ 0, std::min(size.height(), rc.top()) };
const auto bottomRight = til::point{ size.width(), std::min(size.height(), rc.bottom()) };
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 sure @miniksa will agree:

i am surprised we do not have til::rectangle::clamp

Copy link
Member Author

Choose a reason for hiding this comment

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

I mean we do technically have an operator&, but I found it cumbersome to first construct a rectangle (which is rather verbose) just to do & rc.

Copy link
Member

@DHowett DHowett Jul 23, 2021

Choose a reason for hiding this comment

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

Only somewhat verbose 😄

const auto size = _invalidMap.size();
_invalidMap.set(til::rectangle{ 0, rc.top(), size.width(), rc.bottom() } & til::rectangle{ size });

okay I admit, it does look rather cumbersome.

Copy link
Member

Choose a reason for hiding this comment

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

I personally prefer Dustin's, but I'll take either. The structures and operators are tools to make life easier... not a strict requirement.

Copy link
Member Author

Choose a reason for hiding this comment

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

If I'm reading this correctly, there isn't a strong opinion... as I'd like to keep it the way I did it for now, if you don't mind. 😅

@ghost ghost added Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels Jul 23, 2021
@DHowett
Copy link
Member

DHowett commented Jul 23, 2021

Make sure you test unusual scenarios too, like doing a lot of resizing in WT, with multiple panes, and moving between displays of different DPIs (or changing your active DPI)

@lhecker
Copy link
Member Author

lhecker commented Jul 23, 2021

Make sure you test unusual scenarios too, like doing a lot of resizing in WT, with multiple panes, and moving between displays of different DPIs (or changing your active DPI)

I can't spot anything unusual. 👍

@@ -61,7 +61,6 @@ using namespace Microsoft::Console::Types;
// TODO GH 2683: The default constructor should not throw.
DxEngine::DxEngine() :
RenderEngineBase(),
_invalidateFullRows{ true },
Copy link
Member

Choose a reason for hiding this comment

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

Why did you pull this? I presume the answer is:

  1. No one ever set this so we'll always just invalidate a full row.
  2. We determined that we likely won't even need to do differential drawing with a better render strategy anyway so there's no reason to try to tighten down the differential drawing any further in the future by doing partial rows.
    If that's the answer... maybe leave some of that in a comment in InvalidateRectangle so we don't forget.

Copy link
Member Author

@lhecker lhecker Jul 23, 2021

Choose a reason for hiding this comment

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

Yeah basically that. I was touching the only function that uses this field and I doubt this field will ever be useful again, as it's slower to figure out what contains ligatures, compared to just redrawing the entire row. The difference between drawing no text and a full row of text is only ~5μs after all. (Also: YAGNI. 😄)

Copy link
Member

Choose a reason for hiding this comment

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

Fair enough.

@lhecker lhecker merged commit 20e88d3 into main Jul 23, 2021
@lhecker lhecker deleted the dev/lhecker/fix-conhost-dx branch July 23, 2021 18:19
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 Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) Product-Conhost For issues in the Console codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Conhost output is invisible when UseDx is set
3 participants