-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Strawman: Dumb implementation of text D2D effects. #817
Conversation
After building this, I realized you probably actually want to do it on the whole buffer, not just the text layer, which would make things way easier.
Also currently doesn't implement letting you set the shadow color/alpha, size, or offset for the shadow. The effect being on the text means that it's also doesn't affect the cursor or underlines, etc... Note that if you're going to restore invalidation (#778), that effects, including shadow, increase the invalidated area. Suggestions welcome on what the config for this should look like, if any of the other built-in d2d effects should be supported. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea in practice, but you're right.... this probably needs to somehow apply at the entire display/render target surface, not just the text itself.
I'd rather have an effect apply to the entire composition so I don't have to be concerned with how each layer is drawn/composed.
If we do that, it might also work properly with partial invalidation... depending on where we can apply the effect at a higher level.
However.... do note that while this is cool playing around, I probably can't accept this right away or I'll have to accept it as nerfed out additional functions that aren't actually usable code yet (like _DrawGlowTextRun
which isn't really hooked up yet). It's way more important to us to get the base layers of rendering up to speed and the differential drawing up and then focus on the fun effects a little later.
I'm also going to have to personally cross the bridge of figuring out how to carry settings down from the TerminalControl
interface into the renderer itself to enable other such preferences like which cleartype/antialiasing the user would like. And I was planning on working it through with @zadjii-msft. So if you wait a little while until I get to put more effort into this, some of those things will be solved for you.
@@ -11,20 +11,15 @@ | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ClCompile Include="pch.cpp" /> | |||
<ClCompile Include="KeyChord.cpp" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's going on here? Why are these getting removed? (and below)
It doesn't look like you otherwise manipulated this module. Were these moved out by someone else and the filters wasn't updated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea! I guess so, as the .vcxproj wasn't changed.
src/renderer/dx/CustomTextRenderer.h
Outdated
@@ -18,6 +22,8 @@ namespace Microsoft::Console::Render | |||
const D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE) | |||
{ | |||
this->renderTarget = renderTarget; | |||
this->textRenderContext = textRenderContext; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're using tabs. we use 4 spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, missed one!
@@ -3,13 +3,17 @@ | |||
|
|||
#pragma once | |||
|
|||
#include <d2d1_3.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this probably belongs in a precomp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weirdly, it is in the precomp.h for all the projects I found that should be using it, but without it the build failed, but I didn't look too much into it. Definitely a FIXME.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correction: It is explicitly #include
d in the precomp.h
for RendererDx
, but this file ends up included in a whole bunch of other projects. I couldn't find an appropriate file to add it, e.g. one with other #include <d2d1*.h>
lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this end up included in other projects? Shouldn't it just be scoped inside DxRenderer
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's included in DxRenderer.hpp
rather than forwarded, and that is included in InteractivityWin32
's Window.cpp
and TerminalControl
s TermControl.{h,cpp}
. Seems like the right place to put it going by current style would be DxRenderer.hpp
then, but better for those to have a pimpl pattern or get them onto IRenderEngine
.
Definitely: this should have a bunch more iteration, just wanted to get some feedback early.
I'm thinking that if the custom text renderer stuff is reverted but for using the provided bitmap render target that invalidation at the text run level should work fine, For applying the effect either:
While true, a text shadow does make very low acrylic opacities usable, so it still is a functionality improvement... for a fun effect 😉
|
@miniksa, I added some placeholder parsing, I'm assuming you would want a general I also... simplified? the rendering, switching between using the bitmap render target and the dxgi render target for all draw calls. Since a device context is also a render target, that means we end up with basically the same contents in Side note, while poking around, I'm curious about I also noticed what looks like some low hanging fruit for caching |
Sorry @simonbuchan, you have way more time to think about this right now than I do. I just know that I want to get back in here as soon as I can. I haven't thought through the right way to do settings yet. Simplifying the rendering/switching between two of the interfaces to the one that doesn't have to be re-queried is goodness that I would want to get to. The Creating brushes is expensive-ish. That's why to some degree I cached the foreground/background ones and just keep adjusting their colors/opacities as text is drawn. Then I came through and added a bunch of other complexity to the renderer that didn't use those two brushes. If we can just get away with one |
No problem, this is mostly just me getting my feet wet in the codebase and seeing how stuff fits together.
Hmm, even after commenting out the
It was pretty easy to do all this for the |
When testing I'm not sure why it's working correctly without I usually use a full WPR trace though to compare performance characteristics, not something like a timed command. Sometimes when you make one part of the code faster, a different part decides to then waste the time and they actually both need to be fixed for an overall improvement. That's hard to see from a simple wall-clock analysis and easier with a hot-stack-trace.
Alright, that's a fine conclusion. I don't mind either way. We have a lot of minor PRs for people getting their feet wet, but not bothering until something substantial is fine too. |
Ah, you're right - good to know!
Ah, yes I was a bit misleading there. I actually did profile first and saw the majority of the time spent on text layout and basically none spent on the actual rendering commands or the present. I did a timed command and compared against the same redirected to |
@mdtauk That's cool, but it doesn't seem material to the rendering discussion in this thread? |
Got me, I was just commenting on that statusbar in the images above. Comment removed. If these kinds of effects were to become part of the app - and if a statusbar becomes part of the console area (rather than in the window frame below) should these effects affect the status area? |
It's just the existing setting
Not exactly sure what you mean by a status bar or console area, but I would guess by default these settings would be purely for the terminal control itself. If the suggestion of extending the background up into the selected tab is done, it might make sense then? |
@simonbuchan In the trailer video for the new Terminal, it shows a statusbar at the bottom of the window In the various mock ups I have done to illustrate ideas I have submitted issues for our responded to, I've included the statusbar into the console area itself, not below it on the window acrylic itself. So if these fun text effects got added officially, and if the statusbar was to be part of the console view itself, should it be affected by the effect, or should it be immune? |
Once #3468 is merged, can we use that as a base to update this PR to bring in more cool visual D2D features? |
Honestly, I'm not sure we're ever going to really ship this in Windows Terminal 1.0 built in. To me, it makes a lot more sense as an extension. #3468 is pretty similar, but I think it's a polished enough appearance that we could accept it as an experimental feature for now, and move it to an extension in the future. @simonbuchan Do you mind if we close this PR for now? We'll certainly use learnings from it to influence future extensions planning. |
Of course! It was always meant as a strawman, to discuss the value of this and see the code impact, and to be re-written when the code base was more settled (see "Dumb implementation" in the title) That said, implementation aside, I feel if you're going to natively support only one effect, a drop shadow to increase contrast against low-opacity backgrounds would be the one I would pick (which is why I did, of course). I put this down when it reached the basic level needed for the above, and the code base started shifting pretty quickly under it (particularly in settings). I'm happy to try this out again when you start looking at extensions, if you're looking at something to exercise them, maybe. In particular, it seems like packaging effects like #3468 as Direct2D custom effects, so they can be more easily mix-and-matched together with D2D built-in effects by configuration might be a good way to go? In the extreme, you could probably define #3468 in terms of the built in effects (tiled bitmap source for the scanlines, blur and multiply the source for the glow, add the blur and source, multiple that with the scanlines), but that's probably worse performance. |
More for feedback and ideas after I was screwing around with the code,
not really for merging, though this is probably not that far off.
Edit
Updated with settings parsing (though pretty hacky), and applies to all rendering output:
Note the offset x,y settings are not hooked up, but they are other settings you'd probably want. I'm thinking all those should be extracted to a shadow setting block and a shadow renderer effect taking it that can plug in, design wise.
Original
After building this, I realized you probably actually want to do it on
the whole buffer, not just the text layer, which would make things way
easier, and correctly handle cases like the vim bottom separator.
Here's the current shadow effect:
And without acrylic:
The super-dumb displacement effect, also showing a weird limit on the affected output size: