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

iOS PlatformView only sets a maskView when necessary #37434

Merged
merged 2 commits into from
Nov 18, 2022

Conversation

cyanglaz
Copy link
Contributor

@cyanglaz cyanglaz commented Nov 8, 2022

TL;DR

The maskView reduces the performance, and we should avoid the usage as much as possible, details in: flutter/flutter#107486 (comment)

This PR checks whether the the bounding rect of a clip mutator contains the entire PlatformView. If that is the case, we skip that clip mutator because the visual result will be the same.

This is particular helpful when there are multiple PlatformViews in a list view because there is usually a clipRect layer around the whole list view but the PlatformViews aren't really need to be clipped.

Fixes: flutter/flutter#107486

Performance comparison

Before fix:

current

After fix:

fix

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@jmagman
Copy link
Member

jmagman commented Nov 9, 2022

There are scenario test golden failures GOLDEN DIFF FAILED

	-[PlatformViewWithOtherBackdropFilterTests testPlatformView]
	-[TwoPlatformViewsWithOtherBackDropFilterTests testPlatformView]
	-[UnobstructedPlatformViewTests testMultiplePlatformViewsWithOverlays]
	-[UnobstructedPlatformViewTests testMultiplePlatformViewsWithoutOverlays]
	-[PlatformViewMutationTransformTests testPlatformView]
	-[MultiplePlatformViewsBackgroundForegroundTest testPlatformView]
	-[MultiplePlatformViewsTest testPlatformView]

Copy link
Contributor

@stuartmorgan stuartmorgan left a comment

Choose a reason for hiding this comment

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

Are the failing tests false positives from fragile tests, or is this actually causing unexpected side-effects?

@@ -32,6 +32,16 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
}
@end

static bool ClipBoundsContainsPlatformViewBoundingRect(const SkRect& clipBounds,
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs a declaration comment.

It would be especially helpful to explain what the bounds and rect are supposed to be relative to.

Copy link
Contributor

Choose a reason for hiding this comment

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

(And what the matrix is applied to.)

const SkRect& platformViewBoundingRect,
const SkMatrix& transformMatrix,
CGFloat screenScale) {
SkRect transformedClipBounds = transformMatrix.mapRect(clipBounds);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it's just because I'm not familiar with this code, but the logic here doesn't seem very obvious. E.g., I don't know why there's a reverse screen scale applied to one of the parameters (but not the other). Comments explaining why the code here is doing what it is doing would be good.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I rearranged the code in ApplyMutators so that the reverseScreenScale matrix is added later, which helps eliminate the screen scale factor in this method. Hopefully it is now easier to understand.

@@ -32,6 +32,16 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
}
@end

static bool ClipBoundsContainsPlatformViewBoundingRect(const SkRect& clipBounds,
const SkRect& platformViewBoundingRect,
Copy link
Contributor

Choose a reason for hiding this comment

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

Optional nit for here and the local variables: while either snake_case or camelCase are allowed by style for C(++) functions in ObjC++ code, it looks like most of the surrounding code here is C++ using snake_case, so it seems like snake_case for these would be more consistent.

@@ -280,7 +280,9 @@ class FlutterPlatformViewsController {
// T_1 is applied to C_2, T_3 and T_4 are applied to C_5, and T_6 is applied to PLATFORM_VIEW.
//
// After each clip operation, we update the head to the super view of the current head.
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you update the comment here to explain bounding_rect? It's not clear from immediate context what exactly it is the bounds of.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is still missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

clipView.maskView = maskView;
embedded_view.layer.transform =
CATransform3DConcat(GetCATransform3DFromSkMatrix(transformMatrix), reverseTranslate);
if (needMask) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Optional: You could eliminate needMask and just call clipView.maskView = maskView each place you currently have needMask = YES, so there's less local state to track.

@cyanglaz
Copy link
Contributor Author

The failing tests are due a bug, I had the matrix concatenation backwards. Will fix it along with other nits in the next few commits.

@cyanglaz
Copy link
Contributor Author

cyanglaz commented Nov 11, 2022

I'm not sure why mac_host_engine keeps failing on a seemingly unrelated impeller unit test.

[ RUN      ] Play/RuntimeStageTest.CanCreatePipelineFromRuntimeStage/Metal
[ERROR:flutter/fml/backtrace.cc(108)] Caught signal SIGSEGV during program execution.
Frame 0: 0x7ff80d19a177 newRenderPipeline()
Frame 1: 0x7ff80d226b7c __233-[MTLCompiler createVertexStageAndLinkPipelineWithFragment:fragmentVariant:vertexFunction:serializedVertexDescriptor:descriptor:destinationArchive:options:reflection:compileStatistics:fragmentCompileTimeData:error:completionHandler:]_block_invoke.1436
Frame 2: 0x7ff80461c0cc _dispatch_call_block_and_release
Frame 3: 0x7ff80461d317 _dispatch_client_callout
Frame 4: 0x7ff804623317 _dispatch_lane_serial_drain
Frame 5: 0x7ff804623dfd _dispatch_lane_invoke
Frame 6: 0x7ff80462deee _dispatch_workloop_worker_thread
Frame 7: 0x7ff8047d0fd0 _pthread_wqthread
Frame 8: 0x7ff8047cff57 start_wqthread



!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


Failed Command:

/Volumes/Work/s/w/ir/cache/builder/src/out/host_profile/impeller_unittests --gtest_repeat=2 --gtest_shuffle

Exit Code: -11

The same test passed locally.

@cyanglaz
Copy link
Contributor Author

cyanglaz commented Nov 11, 2022

The impeller unit test failure is related to flutter/flutter#114872

@cyanglaz
Copy link
Contributor Author

cyanglaz commented Nov 11, 2022

@stuartmorgan Updated per review comments, PTAL.
I also added a scenario app test which combines transform and clips.

Copy link
Contributor

@stuartmorgan stuartmorgan left a comment

Choose a reason for hiding this comment

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

LGTM other than a couple of missing comments (with the caveat that I'm not familiar with the details of this clipping system, so I'm just trusting you and the tests that all the matrix/transform logic is correct 🙂 ).

@@ -280,7 +280,9 @@ class FlutterPlatformViewsController {
// T_1 is applied to C_2, T_3 and T_4 are applied to C_5, and T_6 is applied to PLATFORM_VIEW.
//
// After each clip operation, we update the head to the super view of the current head.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is still missing.

@@ -241,6 +241,8 @@ - (NSMutableArray*)backdropFilterSubviews {

@interface FlutterClippingMaskView ()

@property(nonatomic) CATransform3D reverseScreenScale;
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs a declaration comment, per style guide.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@cyanglaz
Copy link
Contributor Author

Added comments to explain the bounding_rect parameter and reverseScreenScale property.

@chinmaygarde
Copy link
Member

The presub failure looks related to this patch but the fix ought to be simple. Should be good go soon!

@cyanglaz
Copy link
Contributor Author

The presub failure looks related to this patch but the fix ought to be simple. Should be good go soon!

Yes, I'm currently working on a different local branch and plan to fix it later today.

tests

fix tests

format

review

fix

add scenario tset

more scenario tests

add docs and comments

use offset.zero
@cyanglaz cyanglaz added the autosubmit Merge PR when tree becomes green via auto submit App label Nov 18, 2022
@auto-submit auto-submit bot merged commit 04aea3c into flutter:main Nov 18, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 18, 2022
sourcegraph-bot pushed a commit to sgtest/megarepo that referenced this pull request Nov 18, 2022
…ry (flutter/engine#37434) (#115621)

Commit: 9c9f7818ac16b80e030cd101fe050e9e96f5c1eb
@cyanglaz cyanglaz deleted the platform_view_perf branch November 18, 2022 16:59
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Nov 18, 2022
* 70b7445 Reland Added Badge.count constructor (flutter/flutter#115566)

* 31f8631 fa7e1965e [Impeller] Fix glyph atlas uploads and renders (flutter/engine#37691) (flutter/flutter#115556)

* a1ea383 Label should always be aligned with text in filled input decoration (flutter/flutter#115540)

* c2b2950 Add selection feedback for both selection area and text field (flutter/flutter#115373)

* 0344407 Rev package:pub_semver to the latest version (flutter/flutter#115570)

* ac06523 Add Material 3 support for `Slider` - Part 2  (flutter/flutter#114624)

* b181d07 a2fa4e9 cirrus to luci (flutter/plugins#6711) (flutter/flutter#115573)

* e1efd0d b241e69fd [ui] reland add docs to FragmentShader (flutter/engine#37699) (flutter/flutter#115578)

* efb0694 Remove unused flutter_attach_test_fuchsia (flutter/flutter#115515)

* a5a368c 487ee66f6 [macOS] Merge FlutterRenderer and implementation (flutter/engine#37696) (flutter/flutter#115581)

* 4ff7fc6 Fixes a bug where dragging a collapsed handle in TextField does not vibrate (flutter/flutter#115586)

* 20be280 da9534ea6 [macOS] Consolidate external texture classes (flutter/engine#37703) (flutter/flutter#115585)

* 8a7102e Roll Flutter Engine from da9534ea6534 to d955a72c5604 (3 revisions) (flutter/flutter#115589)

* e1903a2 Roll Flutter Engine from d955a72c5604 to 1e1a4ab3c993 (4 revisions) (flutter/flutter#115592)

* 78390a0 Roll Flutter Engine from 1e1a4ab3c993 to b65c24ce621a (2 revisions) (flutter/flutter#115598)

* 75a0a72 [devicelab] measure entire release folder size, zipped (flutter/flutter#115597)

* 59a01b6 Roll Flutter Engine from b65c24ce621a to 49b52db603cc (3 revisions) (flutter/flutter#115606)

* ec03f1c Revert "[devicelab] measure entire release folder size, zipped (#115597)" (flutter/flutter#115609)

* 710e708 Improve showSnackBar documentation (flutter/flutter#114612)

* 915c3de Roll Flutter Engine from 49b52db603cc to 80b25a302b4c (2 revisions) (flutter/flutter#115608)

* 450f162 Roll Flutter Engine from 80b25a302b4c to e812122e4060 (2 revisions) (flutter/flutter#115614)

* 0b33b85 [devicelab] measure entire release folder size, zipped (flutter/flutter#115612)

* 9379c32 Revert "[devicelab] measure entire release folder size, zipped (#115612)" (flutter/flutter#115617)

* b746557 f27666d2f [macOS] Merge FlutterBackingStore implementations (flutter/engine#37730) (flutter/flutter#115616)

* 5487a7d Roll Flutter Engine from f27666d2f4da to 39f546585b0b (2 revisions) (flutter/flutter#115618)

* f261c2f update comments (flutter/flutter#115603)

* 9c9f781 04aea3c47 iOS PlatformView only sets a maskView when necessary (flutter/engine#37434) (flutter/flutter#115621)

* 6926960 4ca2c1d78 Roll Skia from 55f654bf5cff to 9d56e506b4df (13 revisions) (flutter/engine#37739) (flutter/flutter#115625)

* de4c0b1 Use `double.isNaN` instead of `... == double.nan` (which is always false) (flutter/flutter#115424)

* a655f85 a62736769 Roll Skia from 9d56e506b4df to d693b4b9fe5e (5 revisions) (flutter/engine#37741) (flutter/flutter#115640)

* 18c8727 f092cd826 Roll Fuchsia Mac SDK from SVtX810D2U_ZgBcpx... to tklUfTsSOVKk49tYq... (flutter/engine#37742) (flutter/flutter#115643)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App platform-ios
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Platform-View List / Grid scrolling is janky on IOS / Android
4 participants