-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
[WinUI] Perf when creating non-trivial grids (and other visual controls) (take 2) #22108
[WinUI] Perf when creating non-trivial grids (and other visual controls) (take 2) #22108
Conversation
@@ -91,6 +91,8 @@ public string AutomationId | |||
} | |||
} | |||
|
|||
public bool IsPlatformViewNew { get; set; } |
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.
The name is terrible. It should be internal
if possible.
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 don't think there is a way to make this internal
if it is a property on IElement
.
Is there a way this could detect if Handler
was null
and became non-null
for the first time? Then maybe we wouldn't need a new bool
property?
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.
Is there a way this could detect if
Handler
wasnull
and became non-null
for the first time? Then maybe we wouldn't need a newbool
property?
I don't think I can simulate it that way because I need to set IsPlatformViewNew
to true
and then back to false
:
- https://github.com/dotnet/maui/pull/22108/files#diff-fe5090f560d95c536e43dfc5f39442add6ad2d8eb555d675bdb4a0f82a30793dR59 - set
IView.IsPlatformViewNew
totrue
. - https://github.com/dotnet/maui/pull/22108/files#diff-fe5090f560d95c536e43dfc5f39442add6ad2d8eb555d675bdb4a0f82a30793dR92 - set
IView.IsPlatformViewNew
tofalse
.
an alternative which I would consider the best (in an ideal world) would be to pass a flag to:
_mapper.UpdateProperties(this, VirtualView); |
but unfortunately then I would need to propagate that flag here:
maui/src/Core/src/PropertyMapper.cs
Line 47 in e33d176
action?.Invoke(viewHandler, virtualView); |
and that would mean changing the way mappers are defined:
maui/src/Core/src/PropertyMapper.cs
Line 18 in e33d176
protected readonly Dictionary<string, Action<IElementHandler, IElement>> _mapper = new(StringComparer.Ordinal); |
which seems like a very invasive thing to do (with many and many changes required). That's why I went with the IView.IsPlatformViewNew
flag to avoid making changes to mappers.
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 don't think there is a way to make this
internal
if it is a property onIElement
.Is there a way this could detect if
Handler
wasnull
and became non-null
for the first time? Then maybe we wouldn't need a newbool
property?
I was thinking about this a bit more and one alternative idea would be: Do not add Element.IsPlatformViewNew
but rather add two new mapper calls:
- InitializingNewElement
- NoLongerInitializingNewElement
but I would still need to store the state somewhere and mappers are "state-less" AFAIK.
Hey there @MartyIX! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
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.
Based on the changes, needs to update also the Stubs used in the testing projects. For example:
D:\a\_work\1\s\src\Core\tests\DeviceTests.Shared\Stubs\WindowStub.cs(6,28): error CS0535: 'WindowStub' does not implement interface member 'IElement.IsPlatformViewNew' [D:\a\_work\1\s\src\Core\tests\DeviceTests.Shared\Core.DeviceTests.Shared.csproj::TargetFramework=net8.0-android]
16 Error(s)
I tried to fix it in b5d7287. I believe that this PR requires a conceptual review because it's not clear (to me) whether the approach is OK or not. |
@@ -91,6 +91,8 @@ public string AutomationId | |||
} | |||
} | |||
|
|||
public bool IsPlatformViewNew { get; set; } |
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 don't think there is a way to make this internal
if it is a property on IElement
.
Is there a way this could detect if Handler
was null
and became non-null
for the first time? Then maybe we wouldn't need a new bool
property?
AutomationProperties.SetAutomationId(platformView, view.AutomationId); | ||
public static void UpdateAutomationId(this FrameworkElement platformView, IView view) | ||
{ | ||
if (!view.IsPlatformViewNew || view.AutomationId is not null) |
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.
Is the default for AutomationId
null
or string.Empty
? I don't know the answer, so just checking.
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 saw null
when testing it so I used null
but I will re-check.
if (rotationX % 360 == 0 && rotationY % 360 == 0 && rotation % 360 == 0 && | ||
translationX == 0 && translationY == 0 && scaleX == 1 && scaleY == 1) |
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.
Is there a way this could do slightly better if someone set ScaleX
/ScaleY
, but not rotation or translation?
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.
Personally, I think it would be a good start to extract changes from this file to a standalone PR because setting
maui/src/Core/src/Platform/Windows/TransformationExtensions.cs
Lines 21 to 22 in e33d176
frameworkElement.RenderTransformOrigin = new global::Windows.Foundation.Point(anchorX, anchorY); | |
frameworkElement.RenderTransform = new ScaleTransform { ScaleX = scaleX, ScaleY = scaleY }; |
and then setting
frameworkElement.RenderTransform = null; |
feels like RenderTransformOrigin
does not be set at all in that situation and it also seems to be quite costly. I would need to re-measure it but I think this small change would have noticeable effect.
Is there a way this could do slightly better if someone set
ScaleX
/ScaleY
, but not rotation or translation?
I'll check it.
b5d7287
to
be1e415
Compare
2bbd3a0
to
b6f0807
Compare
70ca386
to
84ed8e9
Compare
62e85c0
to
f7bfa48
Compare
Closing in favor of #27042 |
Description of Change
Alternative to #21818 which attempts to implement @jonathanpeppers's idea:
The idea of this PR is to introduce
IView.IsPlatformViewNew
which istrue
when there is a new platform view (which is known to have default values by default). So the first assignment of all properties can take into account this property and skip costly interop operations when an element is being added to the UI tree for the first time.Relevant lines of code:
IView.IsPlatformViewNew
totrue
.IView.IsPlatformViewNew
tofalse
.Notes:
PropertyMapper
's set the same values over and over #17303Performance
Main: 424 ms
PR: 391 ms
Old measumerents
Main: 851 ms
PR: 559 ms
-> 34% faster.
Issues Fixed
Contributes to #21787