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
Remove WindowsGraphics and DeviceContext #3553
Conversation
src/System.Windows.Forms/src/System/Windows/Forms/ScreenDcCache.cs
Outdated
Show resolved
Hide resolved
I've found that we can save quite a bit of allocations and complexity by adding The implementation would be simple and I wouldn't hang new public methods, but given that the interface is public this would still be an API change. Here is the implementation (which we never use directly, but would be rational if someone tried to use it): IntPtr IDeviceContext.GetHdc() => Graphics?.GetHdc() ?? IntPtr.Zero;
void IDeviceContext.ReleaseHdc() => Graphics?.ReleaseHdc(); I think this is a reasonable thing to do given our dependence on I'll have the PR updated with this later along with more numbers and other details. |
On the same page as The only semi-weird thing is that adding |
I've updated the PR, but I need to merge conflicts again. Here are current allocation numbers for invalidating and painting two different forms. The first "MulitpleControls" is in the controls test project.
"ManyControls" is one I've created with a number of controls as well. Here is what it looks like. I'm still iterating on what I've done and reviewing my change but the automated tests pass. |
e4c6b27
to
c47e9c4
Compare
This change removes all of the misc\GDI classes and replaces them with new isolated caches for Font-to-HFONT and "measurement" screen DCs. This reduces significant allocations and complexity and improves performance with these legacy code paths. This also starts changing Graphics wrapping event args to derive from IDeviceContext to allow unifying handling of extraction of HDCs via DeviceContextHDCScope with low overhead. Introduce internal IGraphicsHdcProvider to allow unwrapping IDeviceContext derived paint events. Convert a number of paths to use GDI where possible (notably when there isn't transparency involved). Optimize HBRUSH context to get system brushes when provided with a color that is wrapping a system color.
c47e9c4
to
860be3e
Compare
The design for the changes in this PR is settled. I'm digging through the rest of the paint allocations and will be updating things like comments on classes/methods. |
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.
53% through...
src/System.Windows.Forms/src/System/Windows/Forms/Internal/PaintEventExtensions.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/ButtonInternal/ButtonBaseAdapter.cs
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/PaintEventArgs.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/PaintEventArgs.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Internal/PaintEvent.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Internal/GdiCache.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Internal/ScreenDcCache.cs
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/DrawItemEventArgs.cs
Outdated
Show resolved
Hide resolved
More cleanup, breaking out classes, matching names, clarifying comments. Add ARGB struct to deal with ARGB values and create Mix extension. Add our own SolidBrush to avoid hooking events when created from System colors.
- Update IDeviceContext per API review approval - Move HLSColor to separate file and cleanup - Improve perf of ControlPaint.DrawBorder - Misc cleanup - Add DrawLines overloads - Add StaticPen/Brush helpers to keep from hooking system colors
While I have plenty more to do after this PR, I think the PR here is ready for review. Fundamental components:
|
@weltkante this change should mitigate the wacky HDC scoping issues we've been seeing in the tests- since you've been seeing this you might want to have a look at the caches I've introduced here to move everything to stack based scopes. |
@JeremyKuhne thanks, will have a look and also try your PR later and see if the other problems get resolved |
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.
Massive work 🚀
src/System.Windows.Forms.Primitives/src/System/Windows/Forms/SystemDrawingExtensions.cs
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/ControlPaint.HLSColor.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Internal/DrawingEventArgs.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Internal/DrawingEventArgs.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Internal/DrawingEventArgs.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/Internal/ThreadWorker.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/PaintEventArgs.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms.Primitives/src/System/Windows/Forms/SystemDrawingExtensions.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms.Primitives/src/System/Windows/Forms/SystemDrawingExtensions.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/ControlPaint.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/src/System/Windows/Forms/ErrorProvider.cs
Outdated
Show resolved
Hide resolved
The replacement code for #3391 and #3450 looks good (except the point noted above) and should fix the respective issues. Can't really test the way I did before since there is no GC involved anymore, so nothing to leak into a finalizer I can put a breakpoint on ;-) but manual inspection of the source looks good. Feel free to add both issues to the PR description for resolution if you want. |
Clean up ControlPaint
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.
We did an 1:1 teams code review.
Looked very good to me!
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.
And...checked the tests.
We should look into removing WindowsGraphics in System.Drawing.Common over in dotnet/runtime too at some point |
Resolves #3570
This change removes all of the misc\GDI classes and replaces them with new scopes and isolated caches for Font-to-HFONT and "measurement" screen DCs.
This reduces significant allocations and complexity and improves performance with the related code paths. It also facilitates continued unravelling of HDC Graphics wrapping.
This is the first draft PR. It works and passes tests, with the exception of Maui for some reason which isn't clear. I'm going to be doing more scrubbing, writing tests, and measuring performance. In the meantime I welcome feedback.
Code that lived in
WindowsFont
moved mostly toTextExtensions
and works directly on native GDI handles. The only known difference is that I currently don't cache the font height, but I'm planning to reintroduce that after I walk through the call chains.cc: @Tanya-Solyanik, @KlausLoeffelmann, @RussKie
Microsoft Reviewers: Open in CodeFlow