From 7b5b82e7045a19aa84637c5275a3820276d48cc5 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Mon, 24 Jun 2024 15:33:23 -0400 Subject: [PATCH 01/88] Roll Skia from 0fa58b6ddba0 to 1948fd53e280 (2 revisions) (#53536) https://skia.googlesource.com/skia.git/+log/0fa58b6ddba0..1948fd53e280 2024-06-24 brianosman@google.com Remove asserts about "valid" premultiplied colors in SkPackARGB32 2024-06-24 skia-autoroll@skia-public.iam.gserviceaccount.com Roll ANGLE from e53b3ad72322 to 3c472b45024a (9 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jsimmons@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index aa4d6dbbf8c88..e7029c67bae7b 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '0fa58b6ddba090f7d75dfd03ce0509eda7d1396d', + 'skia_revision': '1948fd53e2807dbfd07f7fc11d85a8d0e5c23589', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 829adbca75967..2371717fa57bd 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: ba8d41ca2ec3714afd8c5735346682be +Signature: dba4f26ae9c9ebddad1a9fc04a66aa18 ==================================================================================================== LIBRARY: etc1 From daa525e536cbbc79eff817b4eb31cebb12528840 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Mon, 24 Jun 2024 16:52:21 -0400 Subject: [PATCH 02/88] Roll Skia from 1948fd53e280 to e20c8b0bac0c (1 revision) (#53540) https://skia.googlesource.com/skia.git/+log/1948fd53e280..e20c8b0bac0c 2024-06-24 mike@reedtribe.org API to return a scaled version of an image If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jsimmons@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index e7029c67bae7b..c7d2b80628600 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '1948fd53e2807dbfd07f7fc11d85a8d0e5c23589', + 'skia_revision': 'e20c8b0bac0caab082d6ed25022cb956147e98c0', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 2371717fa57bd..0fc647d85023e 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: dba4f26ae9c9ebddad1a9fc04a66aa18 +Signature: 4d714fdc37419022a84b674985b7bec1 ==================================================================================================== LIBRARY: etc1 @@ -398,6 +398,7 @@ FILE: ../../../flutter/third_party/skia/modules/pathkit/perf/perfReporter.js FILE: ../../../flutter/third_party/skia/modules/skparagraph/test.html FILE: ../../../flutter/third_party/skia/package-lock.json FILE: ../../../flutter/third_party/skia/relnotes/grvk-shims.md +FILE: ../../../flutter/third_party/skia/relnotes/scaledimage.md FILE: ../../../flutter/third_party/skia/src/gpu/gpu_workaround_list.txt FILE: ../../../flutter/third_party/skia/src/ports/fontations/Cargo.toml FILE: ../../../flutter/third_party/skia/src/sksl/generated/sksl_compute.minified.sksl From 6884e83c13a1b2f84ca4c3e479732fe76024798b Mon Sep 17 00:00:00 2001 From: Gray Mackall <34871572+gmackall@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:36:22 -0700 Subject: [PATCH 03/88] Re-re-land "Upgrade all[most] androidx dependencies to latest" (#53532) Re-re-land https://github.com/flutter/engine/pull/53001 (Reland attempt was at https://github.com/flutter/engine/pull/53462) Unblocked by https://github.com/flutter/flutter/pull/150585, but will still need a manual roll because I will need to re-generate a bunch of lockfiles. Also, https://github.com/flutter/flutter/blob/master/docs/engine/Testing-presubmit-Engine-PRs-with-the-Flutter-framework.md doesn't work (it's blocked on https://github.com/flutter/flutter/issues/149780) so I mostly just have to pray that no new issues occur in the roll. But I believe all issues that came up in the last attempt should be addressed by the above pr and by manual lockfile generation. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- DEPS | 2 +- shell/platform/android/BUILD.gn | 52 ++-- .../android/FlutterFragmentTest.java | 2 +- testing/scenario_app/android/app/build.gradle | 1 + .../scenario_app/android/app/gradle.lockfile | 228 ------------------ .../android/app/src/main/AndroidManifest.xml | 3 +- testing/scenario_app/android/build.gradle | 4 +- .../android/buildscript-gradle.lockfile | 150 ------------ tools/androidx/files.json | 47 ++-- .../android_embedding_bundle/build.gradle | 2 +- 10 files changed, 58 insertions(+), 433 deletions(-) delete mode 100644 testing/scenario_app/android/app/gradle.lockfile delete mode 100644 testing/scenario_app/android/buildscript-gradle.lockfile diff --git a/DEPS b/DEPS index c7d2b80628600..e3e338099f7a4 100644 --- a/DEPS +++ b/DEPS @@ -785,7 +785,7 @@ deps = { 'packages': [ { 'package': 'flutter/android/embedding_bundle', - 'version': 'last_updated:2024-06-12T14:15:49-0700' + 'version': 'last_updated:2024-06-18T12:13:41-0700' } ], 'condition': 'download_android_deps', diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index 40e6912ec335f..041e75ee3fdc5 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -353,37 +353,37 @@ android_java_sources = [ ] embedding_dependencies_jars = [ - "//third_party/android_embedding_dependencies/lib/activity-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/annotation-1.2.0.jar", - "//third_party/android_embedding_dependencies/lib/annotation-experimental-1.1.0.jar", - "//third_party/android_embedding_dependencies/lib/annotations-13.0.jar", + "//third_party/android_embedding_dependencies/lib/activity-1.8.1.jar", + "//third_party/android_embedding_dependencies/lib/annotation-jvm-1.8.0.jar", + "//third_party/android_embedding_dependencies/lib/annotation-experimental-1.4.0.jar", + "//third_party/android_embedding_dependencies/lib/annotations-23.0.0.jar", "//third_party/android_embedding_dependencies/lib/collection-1.1.0.jar", - "//third_party/android_embedding_dependencies/lib/core-1.6.0.jar", - "//third_party/android_embedding_dependencies/lib/core-1.8.0.jar", - "//third_party/android_embedding_dependencies/lib/core-common-2.1.0.jar", - "//third_party/android_embedding_dependencies/lib/core-runtime-2.0.0.jar", + "//third_party/android_embedding_dependencies/lib/core-1.13.1.jar", + "//third_party/android_embedding_dependencies/lib/core-1.10.3.jar", + "//third_party/android_embedding_dependencies/lib/core-common-2.2.0.jar", + "//third_party/android_embedding_dependencies/lib/core-runtime-2.2.0.jar", "//third_party/android_embedding_dependencies/lib/customview-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/fragment-1.1.0.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-1.5.31.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-common-1.5.31.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk7-1.5.30.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk8-1.5.30.jar", - "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-android-1.5.2.jar", - "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-core-jvm-1.5.2.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-common-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-common-java8-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-2.0.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-core-2.0.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-process-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-runtime-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-viewmodel-2.1.0.jar", + "//third_party/android_embedding_dependencies/lib/fragment-1.7.1.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-1.8.22.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-common-1.8.22.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk7-1.8.20.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk8-1.8.20.jar", + "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-android-1.7.1.jar", + "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-core-jvm-1.7.1.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-common-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-common-java8-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-core-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-process-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-runtime-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-viewmodel-2.7.0.jar", "//third_party/android_embedding_dependencies/lib/loader-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/savedstate-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/tracing-1.0.0.jar", + "//third_party/android_embedding_dependencies/lib/savedstate-1.2.1.jar", + "//third_party/android_embedding_dependencies/lib/tracing-1.2.0.jar", "//third_party/android_embedding_dependencies/lib/versionedparcelable-1.1.1.jar", "//third_party/android_embedding_dependencies/lib/viewpager-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/window-1.0.0-beta04.jar", - "//third_party/android_embedding_dependencies/lib/window-java-1.0.0-beta04.jar", + "//third_party/android_embedding_dependencies/lib/window-1.2.0.jar", + "//third_party/android_embedding_dependencies/lib/window-java-1.2.0.jar", ] action("check_imports") { diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java index 0c885997b9132..24d7c6ea32a5c 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java @@ -322,7 +322,7 @@ public void itDelegatesOnBackPressedWithSetFrameworkHandlesBack() { // Calling onBackPressed now will still be handled by Android (the default), // until setFrameworkHandlesBack is set to true. - activity.onBackPressed(); + activity.getOnBackPressedDispatcher().onBackPressed(); verify(mockDelegate, times(0)).onBackPressed(); // Setting setFrameworkHandlesBack to true means the delegate will receive diff --git a/testing/scenario_app/android/app/build.gradle b/testing/scenario_app/android/app/build.gradle index 51eea659614d9..a03b92bdac42f 100644 --- a/testing/scenario_app/android/app/build.gradle +++ b/testing/scenario_app/android/app/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { + namespace = "dev.flutter.scenarios" lintOptions { abortOnError true checkAllWarnings true diff --git a/testing/scenario_app/android/app/gradle.lockfile b/testing/scenario_app/android/app/gradle.lockfile deleted file mode 100644 index f79689a036e99..0000000000000 --- a/testing/scenario_app/android/app/gradle.lockfile +++ /dev/null @@ -1,228 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation:1.0.0=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.asynclayoutinflater:asynclayoutinflater:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cardview:cardview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.concurrent:concurrent-futures:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout-solver:1.1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout:1.1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.coordinatorlayout:coordinatorlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.drawerlayout:drawerlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.interpolator:interpolator:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-ui:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common:2.3.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-process:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.print:print:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.recyclerview:recyclerview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.slidingpanelayout:slidingpanelayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.swiperefreshlayout:swiperefreshlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test.espresso:espresso-core:3.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -androidx.test.espresso:espresso-idling-resource:3.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -androidx.test.ext:junit:1.1.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test.services:storage:1.4.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test:annotation:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test:core:1.5.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test:monitor:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -androidx.test:monitor:1.6.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test:rules:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -androidx.test:runner:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.transition:transition:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable-animated:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.android.tools.analytics-library:protos:30.0.0=lintClassPath -com.android.tools.analytics-library:shared:30.0.0=lintClassPath -com.android.tools.analytics-library:tracker:30.0.0=lintClassPath -com.android.tools.build:aapt2-proto:4.1.0-alpha01-6193524=lintClassPath -com.android.tools.build:apksig:7.0.0=lintClassPath -com.android.tools.build:apkzlib:7.0.0=lintClassPath -com.android.tools.build:builder-model:7.0.0=lintClassPath -com.android.tools.build:builder-test-api:7.0.0=lintClassPath -com.android.tools.build:builder:7.0.0=lintClassPath -com.android.tools.build:manifest-merger:30.0.0=lintClassPath -com.android.tools.ddms:ddmlib:30.0.0=lintClassPath -com.android.tools.external.com-intellij:intellij-core:30.0.0=lintClassPath -com.android.tools.external.com-intellij:kotlin-compiler:30.0.0=lintClassPath -com.android.tools.external.org-jetbrains:uast:30.0.0=lintClassPath -com.android.tools.layoutlib:layoutlib-api:30.0.0=lintClassPath -com.android.tools.lint:lint-api:30.0.0=lintClassPath -com.android.tools.lint:lint-checks:30.0.0=lintClassPath -com.android.tools.lint:lint-gradle:30.0.0=lintClassPath -com.android.tools.lint:lint-model:30.0.0=lintClassPath -com.android.tools.lint:lint:30.0.0=lintClassPath -com.android.tools:annotations:30.0.0=lintClassPath -com.android.tools:common:30.0.0=lintClassPath -com.android.tools:dvlib:30.0.0=lintClassPath -com.android.tools:repository:30.0.0=lintClassPath -com.android.tools:sdk-common:30.0.0=lintClassPath -com.android.tools:sdklib:30.0.0=lintClassPath -com.android:signflinger:7.0.0=lintClassPath -com.android:zipflinger:7.0.0=lintClassPath -com.beust:jcommander:1.78=lintClassPath -com.github.javaparser:javaparser-core:3.17.0=lintClassPath -com.google.android.material:material:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.code.findbugs:jsr305:2.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.code.findbugs:jsr305:3.0.2=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,lintClassPath -com.google.code.gson:gson:2.8.6=lintClassPath -com.google.errorprone:error_prone_annotations:2.3.4=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -com.google.guava:failureaccess:1.0.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -com.google.guava:guava:30.1-android=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.google.guava:guava:30.1-jre=lintClassPath -com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -com.google.j2objc:j2objc-annotations:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -com.google.jimfs:jimfs:1.1=lintClassPath -com.google.protobuf:protobuf-java:3.10.0=lintClassPath -com.googlecode.json-simple:json-simple:1.1=lintClassPath -com.squareup.curtains:curtains:1.0.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-android-core:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-android-instrumentation:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-android-utils:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-object-watcher-android-androidx:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-object-watcher-android-support-fragments:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-object-watcher-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-object-watcher:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:plumber-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark-graph:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark-hprof:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark-log:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.okio:okio:2.2.2=debugAndroidTestRuntimeClasspath -com.squareup:javawriter:2.1.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup:javawriter:2.5.0=lintClassPath -com.sun.activation:javax.activation:1.2.0=lintClassPath -com.sun.istack:istack-commons-runtime:3.0.8=lintClassPath -com.sun.xml.fastinfoset:FastInfoset:1.2.16=lintClassPath -com.thoughtworks.qdox:qdox:1.12.1=lintClassPath -commons-codec:commons-codec:1.10=lintClassPath -commons-io:commons-io:2.4=lintClassPath -commons-logging:commons-logging:1.2=lintClassPath -info.picocli:picocli:4.5.2=lintClassPath -it.unimi.dsi:fastutil:8.4.0=lintClassPath -jakarta.activation:jakarta.activation-api:1.2.1=lintClassPath -jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=lintClassPath -javax.inject:javax.inject:1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -jline:jline:2.14.6=lintClassPath -junit:junit:4.12=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -junit:junit:4.13.1=lintClassPath -junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -net.java.dev.jna:jna-platform:5.6.0=lintClassPath -net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath -net.sf.jopt-simple:jopt-simple:4.9=lintClassPath -net.sf.kxml:kxml2:2.3.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -org.apache.ant:ant-antlr:1.10.9=lintClassPath -org.apache.ant:ant-junit:1.10.9=lintClassPath -org.apache.ant:ant-launcher:1.10.9=lintClassPath -org.apache.ant:ant:1.10.9=lintClassPath -org.apache.commons:commons-compress:1.20=lintClassPath -org.apache.httpcomponents:httpclient:4.5.6=lintClassPath -org.apache.httpcomponents:httpcore:4.4.10=lintClassPath -org.apache.httpcomponents:httpmime:4.5.6=lintClassPath -org.bouncycastle:bcpkix-jdk15on:1.56=lintClassPath -org.bouncycastle:bcprov-jdk15on:1.56=lintClassPath -org.checkerframework:checker-compat-qual:2.5.5=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -org.checkerframework:checker-qual:3.5.0=lintClassPath -org.codehaus.groovy:groovy-all:3.0.7=lintClassPath -org.codehaus.groovy:groovy-ant:3.0.7=lintClassPath -org.codehaus.groovy:groovy-astbuilder:3.0.7=lintClassPath -org.codehaus.groovy:groovy-cli-picocli:3.0.7=lintClassPath -org.codehaus.groovy:groovy-console:3.0.7=lintClassPath -org.codehaus.groovy:groovy-datetime:3.0.7=lintClassPath -org.codehaus.groovy:groovy-docgenerator:3.0.7=lintClassPath -org.codehaus.groovy:groovy-groovydoc:3.0.7=lintClassPath -org.codehaus.groovy:groovy-groovysh:3.0.7=lintClassPath -org.codehaus.groovy:groovy-jmx:3.0.7=lintClassPath -org.codehaus.groovy:groovy-json:3.0.7=lintClassPath -org.codehaus.groovy:groovy-jsr223:3.0.7=lintClassPath -org.codehaus.groovy:groovy-macro:3.0.7=lintClassPath -org.codehaus.groovy:groovy-nio:3.0.7=lintClassPath -org.codehaus.groovy:groovy-servlet:3.0.7=lintClassPath -org.codehaus.groovy:groovy-sql:3.0.7=lintClassPath -org.codehaus.groovy:groovy-swing:3.0.7=lintClassPath -org.codehaus.groovy:groovy-templates:3.0.7=lintClassPath -org.codehaus.groovy:groovy-test-junit5:3.0.7=lintClassPath -org.codehaus.groovy:groovy-test:3.0.7=lintClassPath -org.codehaus.groovy:groovy-testng:3.0.7=lintClassPath -org.codehaus.groovy:groovy-xml:3.0.7=lintClassPath -org.codehaus.groovy:groovy:3.0.7=lintClassPath -org.glassfish.jaxb:jaxb-runtime:2.3.2=lintClassPath -org.glassfish.jaxb:txw2:2.3.2=lintClassPath -org.hamcrest:hamcrest-core:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,lintClassPath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.hamcrest:hamcrest-integration:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -org.hamcrest:hamcrest-library:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -org.jacoco:org.jacoco.agent:0.8.8=androidJacocoAnt -org.jacoco:org.jacoco.ant:0.8.8=androidJacocoAnt -org.jacoco:org.jacoco.core:0.8.8=androidJacocoAnt -org.jacoco:org.jacoco.report:0.8.8=androidJacocoAnt -org.jetbrains.intellij.deps:trove4j:1.0.20181211=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath -org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-daemon-embeddable:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.6.10=kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-reflect:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-script-runtime:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-stdlib-common:1.4.21=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-stdlib-common:1.6.10=apiDependenciesMetadata,debugApiDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,releaseApiDependenciesMetadata -org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-stdlib:1.4.21=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -org.jetbrains.kotlin:kotlin-stdlib:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-stdlib:1.6.10=apiDependenciesMetadata,debugApiDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,releaseApiDependenciesMetadata -org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains:annotations:13.0=androidTestImplementationDependenciesMetadata,apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.junit.jupiter:junit-jupiter-api:5.7.0=lintClassPath -org.junit.jupiter:junit-jupiter-engine:5.7.0=lintClassPath -org.junit.platform:junit-platform-commons:1.7.0=lintClassPath -org.junit.platform:junit-platform-engine:1.7.0=lintClassPath -org.junit.platform:junit-platform-launcher:1.7.0=lintClassPath -org.junit:junit-bom:5.7.0=lintClassPath -org.jvnet.staxex:stax-ex:1.8.1=lintClassPath -org.opentest4j:opentest4j:1.2.0=lintClassPath -org.ow2.asm:asm-analysis:7.0=lintClassPath -org.ow2.asm:asm-analysis:9.2=androidJacocoAnt -org.ow2.asm:asm-commons:7.0=lintClassPath -org.ow2.asm:asm-commons:9.2=androidJacocoAnt -org.ow2.asm:asm-tree:7.0=lintClassPath -org.ow2.asm:asm-tree:9.2=androidJacocoAnt -org.ow2.asm:asm-util:7.0=lintClassPath -org.ow2.asm:asm:7.0=lintClassPath -org.ow2.asm:asm:9.2=androidJacocoAnt -org.testng:testng:7.3.0=lintClassPath -xerces:xercesImpl:2.12.0=lintClassPath -xml-apis:xml-apis:1.4.01=lintClassPath -empty=androidApis,androidJdkImage,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testFixturesApiDependenciesMetadata,testFixturesCompileOnlyDependenciesMetadata,testFixturesDebugApiDependenciesMetadata,testFixturesDebugCompileOnlyDependenciesMetadata,testFixturesDebugImplementationDependenciesMetadata,testFixturesDebugIntransitiveDependenciesMetadata,testFixturesDebugRuntimeOnlyDependenciesMetadata,testFixturesImplementationDependenciesMetadata,testFixturesIntransitiveDependenciesMetadata,testFixturesReleaseApiDependenciesMetadata,testFixturesReleaseCompileOnlyDependenciesMetadata,testFixturesReleaseImplementationDependenciesMetadata,testFixturesReleaseIntransitiveDependenciesMetadata,testFixturesReleaseRuntimeOnlyDependenciesMetadata,testFixturesRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata diff --git a/testing/scenario_app/android/app/src/main/AndroidManifest.xml b/testing/scenario_app/android/app/src/main/AndroidManifest.xml index e99d9ae8ae6b5..e400c24567a89 100644 --- a/testing/scenario_app/android/app/src/main/AndroidManifest.xml +++ b/testing/scenario_app/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> Date: Tue, 25 Jun 2024 07:01:09 +0900 Subject: [PATCH 04/88] [macOS] Generate universal gen_snapshots (#53524) This reverts commit ac4c31ac97552681ce7405e60358f755b514b653 (#52913). This relands commit 4e33c102e56e9b3e9898c93c06373066c7eefc92 (#52885). Previously, the `gen_snapshot_arm64` and `gen_snapshot_x64` binaries used by the tool were all built for x64 architecture. As such, developers building apps with Flutter rely on Rosetta translation with every build. This refactors the gen_snapshot build rules on macOS hosts to consistently produce `gen_snapshot_arm64` and `gen_snapshot_x64` binaries with the target architecture of the build but with as universal binaries with both host architectures. ## arm64 host build Prior to this patch we emitted: * gen_snapshot_arm64 (arch: x64, target_arch: simarm64) After this patch, we emit: * artifacts_x64/gen_snapshot_arm64 (arch: x64, target_arch: simarm64) * artifacts_arm64/gen_snapshot_arm64 (arch: arm64, target_arch: arm64) * gen_snapshot_arm64 (universal binary composed of both of the above) ## x64 host build Prior to this patch we emitted: * gen_snapshot_x64 (arch: x64, target_arch: x64) After this patch, we emit: * artifacts_x64/gen_snapshot_x64 (arch: x64, target_arch: x64) * artifacts_arm64/gen_snapshot_x64 (arch: arm64, target_arch: simx64) * gen_snapshot_x64 (universal binary composed of both of the above) Note that host builds on macOS currently default to a host architecture of x64 (can be overridden via `--force-mac-arm64`) regardless of host architecture and thus, the build itself relies on Rosetta translation when invoked on Apple Silicon arm64 hardware. This is to ensure a consistent build in CI regardless of bot architecture. See: https://github.com/flutter/engine/blob/6fa734d686888a39add026a2a98d6ec311c23efb/tools/gn#L502-L505 Issue: https://github.com/flutter/flutter/issues/101138 Issue: https://github.com/flutter/flutter/issues/69157 Related issue: https://github.com/flutter/flutter/issues/103386 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- build/archives/BUILD.gn | 4 +-- ci/licenses_golden/excluded_files | 1 + lib/snapshot/BUILD.gn | 54 ++++++++++++++++++++++++++----- sky/tools/create_macos_binary.py | 54 +++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 10 deletions(-) create mode 100755 sky/tools/create_macos_binary.py diff --git a/build/archives/BUILD.gn b/build/archives/BUILD.gn index 899a031829085..0e327b4cf763a 100644 --- a/build/archives/BUILD.gn +++ b/build/archives/BUILD.gn @@ -283,8 +283,8 @@ if (is_mac) { output = "$full_platform_name$suffix/gen_snapshot.zip" files = [ { - source = "$root_out_dir/gen_snapshot_$target_cpu" - destination = "gen_snapshot_$target_cpu" + source = "${root_out_dir}/gen_snapshot_${target_cpu}" + destination = "gen_snapshot_${target_cpu}" }, ] } diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 37a5f894c5cac..859cf03ca6fa3 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -424,6 +424,7 @@ ../../../flutter/sky/tools/create_embedder_framework.py ../../../flutter/sky/tools/create_full_ios_framework.py ../../../flutter/sky/tools/create_ios_framework.py +../../../flutter/sky/tools/create_macos_binary.py ../../../flutter/sky/tools/create_macos_framework.py ../../../flutter/sky/tools/create_macos_gen_snapshots.py ../../../flutter/sky/tools/create_xcframework.py diff --git a/lib/snapshot/BUILD.gn b/lib/snapshot/BUILD.gn index 8f9dd526fb669..e048a33b45cb4 100644 --- a/lib/snapshot/BUILD.gn +++ b/lib/snapshot/BUILD.gn @@ -186,16 +186,54 @@ if (host_os == "mac" && target_os != "mac" && # # This target is used for builds targeting macOS. if (host_os == "mac" && target_os == "mac") { - copy("create_macos_gen_snapshots") { - # The toolchain-specific output directory. For cross-compiles, this is a - # clang-x64 or clang-arm64 subdirectory of the top-level build directory. - host_output_dir = - get_label_info("$dart_src/runtime/bin:gen_snapshot($host_toolchain)", - "root_out_dir") + template("build_mac_gen_snapshot") { + assert(defined(invoker.host_arch)) + host_cpu = invoker.host_arch - sources = [ "${host_output_dir}/gen_snapshot" ] + build_toolchain = "//build/toolchain/mac:clang_$host_cpu" + if (host_cpu == target_cpu) { + gen_snapshot_target_name = "gen_snapshot_host_targeting_host" + } else { + gen_snapshot_target_name = "gen_snapshot" + } + gen_snapshot_target = + "$dart_src/runtime/bin:$gen_snapshot_target_name($build_toolchain)" + + copy(target_name) { + # The toolchain-specific output directory. For cross-compiles, this is a + # clang-x64 or clang-arm64 subdirectory of the top-level build directory. + output_dir = get_label_info(gen_snapshot_target, "root_out_dir") + + sources = [ "${output_dir}/${gen_snapshot_target_name}" ] + outputs = + [ "${root_out_dir}/artifacts_$host_cpu/gen_snapshot_${target_cpu}" ] + deps = [ gen_snapshot_target ] + } + } + + build_mac_gen_snapshot("create_macos_gen_snapshot_arm64_${target_cpu}") { + host_arch = "arm64" + } + + build_mac_gen_snapshot("create_macos_gen_snapshot_x64_${target_cpu}") { + host_arch = "x64" + } + + action("create_macos_gen_snapshots") { + script = "//flutter/sky/tools/create_macos_binary.py" outputs = [ "${root_out_dir}/gen_snapshot_${target_cpu}" ] - deps = [ "$dart_src/runtime/bin:gen_snapshot($host_toolchain)" ] + args = [ + "--in-arm64", + rebase_path("${root_out_dir}/artifacts_arm64/gen_snapshot_${target_cpu}"), + "--in-x64", + rebase_path("${root_out_dir}/artifacts_x64/gen_snapshot_${target_cpu}"), + "--out", + rebase_path("${root_out_dir}/gen_snapshot_${target_cpu}"), + ] + deps = [ + ":create_macos_gen_snapshot_arm64_${target_cpu}", + ":create_macos_gen_snapshot_x64_${target_cpu}", + ] } } diff --git a/sky/tools/create_macos_binary.py b/sky/tools/create_macos_binary.py new file mode 100755 index 0000000000000..687b53c65581b --- /dev/null +++ b/sky/tools/create_macos_binary.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import argparse +import os +import subprocess +import sys + + +def canonical_path(path): + """Returns the canonical path for the input path. + If the input path is not absolute, it is treated as relative to the engine + source tree's buildroot directory.""" + if os.path.isabs(path): + return path + buildroot_dir = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', '..', '..', '..')) + return os.path.join(buildroot_dir, path) + + +def assert_file_exists(binary_path, arch): + if not os.path.isfile(binary_path): + print('Cannot find macOS %s binary at %s' % (arch, binary_path)) + sys.exit(1) + + +def create_universal_binary(in_arm64, in_x64, out): + subprocess.check_call(['lipo', in_arm64, in_x64, '-create', '-output', out]) + + +def main(): + parser = argparse.ArgumentParser( + description='Creates a universal binary from input arm64, x64 binaries' + ) + parser.add_argument('--in-arm64', type=str, required=True) + parser.add_argument('--in-x64', type=str, required=True) + parser.add_argument('--out', type=str, required=True) + args = parser.parse_args() + + in_arm64 = canonical_path(args.in_arm64) + in_x64 = canonical_path(args.in_x64) + out = canonical_path(args.out) + + assert_file_exists(in_arm64, 'arm64') + assert_file_exists(in_x64, 'x64') + create_universal_binary(in_arm64, in_x64, out) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) From 1fb20a297302073839e90202a9fef4831d65a055 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Mon, 24 Jun 2024 18:05:38 -0400 Subject: [PATCH 05/88] Roll Dart SDK from 5df89347bddf to c187d4b3ec88 (1 revision) (#53542) https://dart.googlesource.com/sdk.git/+log/5df89347bddf..c187d4b3ec88 2024-06-24 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-295.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jsimmons@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 22 +++++++++++----------- sky/packages/sky_engine/LICENSE | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/DEPS b/DEPS index e3e338099f7a4..b3cda3e073606 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '5df89347bddf47cb5fa829f03d19ed77dd5ec2fd', + 'dart_revision': 'c187d4b3ec889b1473e9eb7a031f1a6d065770a5', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py @@ -72,10 +72,10 @@ vars = { 'dart_protobuf_gn_rev': 'ca669f79945418f6229e4fef89b666b2a88cbb10', 'dart_protobuf_rev': 'ccf104dbc36929c0f8708285d5f3a8fae206343e', 'dart_pub_rev': 'ddc1c2fd2e2a7cd94a0b92ea033961a25f4ad517', - 'dart_tools_rev': '4321aecf2cb618dceab5d90adf0cb2ef7207169c', + 'dart_tools_rev': 'e660a68dce659311fb47735ab00365e26fca2fe3', 'dart_watcher_rev': 'c00fc2a6cd869cdebbc52e00af3d912d25745729', 'dart_web_rev': '2fe754fb396cb9b87010f0318cfbfc5408346c48', - 'dart_webdev_rev': 'eccc7d87982b23f666d5e3e09953dca59ca094e4', + 'dart_webdev_rev': 'c56611255f3f02642da10750448a8c90a9fa7b47', 'dart_webkit_inspection_protocol_rev': '5740cc91eaeb13a02007b77b128fccf4b056db6e', 'dart_yaml_edit_rev': '08a146ef8f2c7aba908d2017c9ec840b882c9e51', @@ -380,13 +380,13 @@ deps = { Var('dart_git') + '/crypto.git@813e35e913d12e16de67ac57523cd0ff4b07c012', 'src/flutter/third_party/dart/third_party/pkg/csslib': - Var('dart_git') + '/csslib.git@23c314bb6b247a71348cfb0987ba0eb29574abb6', + Var('dart_git') + '/csslib.git@b70fef222c8a98abca39c3f729ec34632089697e', 'src/flutter/third_party/dart/third_party/pkg/dart_style': Var('dart_git') + '/dart_style.git@a6ad7693555a9add6f98ad6fd94de80d35c89415', 'src/flutter/third_party/dart/third_party/pkg/dartdoc': - Var('dart_git') + '/dartdoc.git@6330a13e3da84b710867af26e343d0b1a4381bc1', + Var('dart_git') + '/dartdoc.git@88df88c9278ec4ec31df818f3ae33d4f91c8cd64', 'src/flutter/third_party/dart/third_party/pkg/file': Var('dart_git') + '/external/github.com/google/file.dart@07cacaed6679a173e29176747e6ce0325742749f', @@ -401,7 +401,7 @@ deps = { Var('dart_git') + '/html.git@3bc803d7e655491b243418f19300ef0c6112bcea', 'src/flutter/third_party/dart/third_party/pkg/http': - Var('dart_git') + '/http.git@8c325b9ca33d878a86d69c5048a8e6e18379663c', + Var('dart_git') + '/http.git@4d8e7ef73d6135a8cc9b5e53db1beb43977d44b0', 'src/flutter/third_party/dart/third_party/pkg/http_multi_server': Var('dart_git') + '/http_multi_server.git@25941e260658efb324de857e6022f418faf9bdd1', @@ -443,7 +443,7 @@ deps = { Var('dart_git') + '/path.git@04807b61c25f98f328b322ec511451f9f86f98bb', 'src/flutter/third_party/dart/third_party/pkg/pool': - Var('dart_git') + '/pool.git@88e463600c636a0d8cdb5dc306524ebf04b06baf', + Var('dart_git') + '/pool.git@832c5ab5eaee444354a8c796f7998bf744f169af', 'src/flutter/third_party/dart/third_party/pkg/protobuf': Var('dart_git') + '/protobuf.git' + '@' + Var('dart_protobuf_rev'), @@ -452,7 +452,7 @@ deps = { Var('dart_git') + '/pub.git' + '@' + Var('dart_pub_rev'), 'src/flutter/third_party/dart/third_party/pkg/pub_semver': - Var('dart_git') + '/pub_semver.git@a9025f3cc23ebb0f86c0af8759d95306b9133ce0', + Var('dart_git') + '/pub_semver.git@dfcad38866fb1e94e8ca91bff3dddd5189fb0794', 'src/flutter/third_party/dart/third_party/pkg/shelf': Var('dart_git') + '/shelf.git@2536c15a562cb183dabbc628824a215663830325', @@ -476,7 +476,7 @@ deps = { Var('dart_git') + '/stream_channel.git@b41ff7a25395ace8b23e454e3d1a3459a71306ca', 'src/flutter/third_party/dart/third_party/pkg/string_scanner': - Var('dart_git') + '/string_scanner.git@7b37c1b3d1ca6b581792e6ba385f651573af4a45', + Var('dart_git') + '/string_scanner.git@e1cab8f0538b50f6d7180598752cf5a7e07e74db', 'src/flutter/third_party/dart/third_party/pkg/tar': Var('dart_git') + '/external/github.com/simolus3/tar.git@552a49d7595e444184d4f91e9afd533aa253a31d', @@ -494,7 +494,7 @@ deps = { Var('dart_git') + '/tools.git' + '@' + Var('dart_tools_rev'), 'src/flutter/third_party/dart/third_party/pkg/typed_data': - Var('dart_git') + '/typed_data.git@d14f9654f7a5d6baa7dcc27691bd0fa56769fb67', + Var('dart_git') + '/typed_data.git@85299290551297a28202b6e7a177bb787f790ffd', 'src/flutter/third_party/dart/third_party/pkg/watcher': Var('dart_git') + '/watcher.git' + '@' + Var('dart_watcher_rev'), @@ -512,7 +512,7 @@ deps = { Var('dart_git') + '/external/github.com/google/webkit_inspection_protocol.dart.git' + '@' + Var('dart_webkit_inspection_protocol_rev'), 'src/flutter/third_party/dart/third_party/pkg/yaml': - Var('dart_git') + '/yaml.git@7873b3fb9f16ec83bc7778fed58615fa91f1f042', + Var('dart_git') + '/yaml.git@4cf24ca3bbcb2cd8cbea32fdd355ee5d0a597247', 'src/flutter/third_party/dart/third_party/pkg/yaml_edit': Var('dart_git') + '/yaml_edit.git' + '@' + Var('dart_yaml_edit_rev'), diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index bd9122f6aa6ed..abc923e0bf63c 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/5df89347bddf47cb5fa829f03d19ed77dd5ec2fd +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/c187d4b3ec889b1473e9eb7a031f1a6d065770a5 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From 63c240384b6353e3cf19f1fda339206d787b75fd Mon Sep 17 00:00:00 2001 From: David Iglesias Date: Mon, 24 Jun 2024 15:15:11 -0700 Subject: [PATCH 06/88] [web] Reland "Fix focus management for text fields (#51009)" (#53537) Relands: [**Fix focus management for text fields** (#51009)](https://github.com/flutter/engine/pull/51009) by: * Reverting commit: https://github.com/flutter/engine/commit/cf3ac2d0f5c68b9979c1b7e24a43d41b4d06e5ef (https://github.com/flutter/engine/pull/53502). * Keeping the new `ViewFocusBinding` disabled, as [suggested](https://github.com/flutter/engine/pull/51009#discussion_r1649500122). [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- lib/web_ui/lib/src/engine/dom.dart | 17 +- .../lib/src/engine/keyboard_binding.dart | 2 +- .../view_focus_binding.dart | 4 +- .../lib/src/engine/pointer_binding.dart | 16 ++ .../src/engine/text_editing/text_editing.dart | 216 ++++++--------- lib/web_ui/test/engine/text_editing_test.dart | 248 +++++++++--------- 6 files changed, 250 insertions(+), 253 deletions(-) diff --git a/lib/web_ui/lib/src/engine/dom.dart b/lib/web_ui/lib/src/engine/dom.dart index b11e9e97a7458..622cf3f2a2dd1 100644 --- a/lib/web_ui/lib/src/engine/dom.dart +++ b/lib/web_ui/lib/src/engine/dom.dart @@ -658,7 +658,16 @@ extension DomElementExtension on DomElement { external JSNumber? get _tabIndex; double? get tabIndex => _tabIndex?.toDartDouble; - external JSVoid focus(); + @JS('focus') + external JSVoid _focus(JSAny options); + + void focus({bool? preventScroll, bool? focusVisible}) { + final Map options = { + if (preventScroll != null) 'preventScroll': preventScroll, + if (focusVisible != null) 'focusVisible': focusVisible, + }; + _focus(options.toJSAnyDeep); + } @JS('scrollTop') external JSNumber get _scrollTop; @@ -2249,9 +2258,11 @@ extension DomKeyboardEventExtension on DomKeyboardEvent { external JSBoolean? get _repeat; bool? get repeat => _repeat?.toDart; + // Safari injects synthetic keyboard events after auto-complete that don't + // have a `shiftKey` attribute, so this property must be nullable. @JS('shiftKey') - external JSBoolean get _shiftKey; - bool get shiftKey => _shiftKey.toDart; + external JSBoolean? get _shiftKey; + bool? get shiftKey => _shiftKey?.toDart; @JS('isComposing') external JSBoolean get _isComposing; diff --git a/lib/web_ui/lib/src/engine/keyboard_binding.dart b/lib/web_ui/lib/src/engine/keyboard_binding.dart index 85bea97039e0a..f70456e42239c 100644 --- a/lib/web_ui/lib/src/engine/keyboard_binding.dart +++ b/lib/web_ui/lib/src/engine/keyboard_binding.dart @@ -207,7 +207,7 @@ class FlutterHtmlKeyboardEvent { num? get timeStamp => _event.timeStamp; bool get altKey => _event.altKey; bool get ctrlKey => _event.ctrlKey; - bool get shiftKey => _event.shiftKey; + bool get shiftKey => _event.shiftKey ?? false; bool get metaKey => _event.metaKey; bool get isComposing => _event.isComposing; diff --git a/lib/web_ui/lib/src/engine/platform_dispatcher/view_focus_binding.dart b/lib/web_ui/lib/src/engine/platform_dispatcher/view_focus_binding.dart index 3a10c4ab723c9..31acaf7ca9273 100644 --- a/lib/web_ui/lib/src/engine/platform_dispatcher/view_focus_binding.dart +++ b/lib/web_ui/lib/src/engine/platform_dispatcher/view_focus_binding.dart @@ -51,7 +51,7 @@ final class ViewFocusBinding { if (state == ui.ViewFocusState.focused) { // Only move the focus to the flutter view if nothing inside it is focused already. if (viewId != _viewId(domDocument.activeElement)) { - viewElement?.focus(); + viewElement?.focus(preventScroll: true); } } else { viewElement?.blur(); @@ -70,7 +70,7 @@ final class ViewFocusBinding { late final DomEventListener _handleKeyDown = createDomEventListener((DomEvent event) { event as DomKeyboardEvent; - if (event.shiftKey) { + if (event.shiftKey ?? false) { _viewFocusDirection = ui.ViewFocusDirection.backward; } }); diff --git a/lib/web_ui/lib/src/engine/pointer_binding.dart b/lib/web_ui/lib/src/engine/pointer_binding.dart index f0b2b75c8e521..741761c434515 100644 --- a/lib/web_ui/lib/src/engine/pointer_binding.dart +++ b/lib/web_ui/lib/src/engine/pointer_binding.dart @@ -982,6 +982,22 @@ class _PointerAdapter extends _BaseAdapter with _WheelEventListenerMixin { ); _convertEventsToPointerData(data: pointerData, event: event, details: down); _callback(event, pointerData); + + if (event.target == _viewTarget) { + // Ensure smooth focus transitions between text fields within the Flutter view. + // Without preventing the default and this delay, the engine may not have fully + // rendered the next input element, leading to the focus incorrectly returning to + // the main Flutter view instead. + // A zero-length timer is sufficient in all tested browsers to achieve this. + event.preventDefault(); + Timer(Duration.zero, () { + EnginePlatformDispatcher.instance.requestViewFocusChange( + viewId: _view.viewId, + state: ui.ViewFocusState.focused, + direction: ui.ViewFocusDirection.undefined, + ); + }); + } }); // Why `domWindow` you ask? See this fiddle: https://jsfiddle.net/ditman/7towxaqp diff --git a/lib/web_ui/lib/src/engine/text_editing/text_editing.dart b/lib/web_ui/lib/src/engine/text_editing/text_editing.dart index 0a7a8de1c5514..f1c45b4b8fc58 100644 --- a/lib/web_ui/lib/src/engine/text_editing/text_editing.dart +++ b/lib/web_ui/lib/src/engine/text_editing/text_editing.dart @@ -332,7 +332,8 @@ class EngineAutofillForm { // In order to submit the form when Framework sends a `TextInput.commit` // message, we add a submit button to the form. - final DomHTMLInputElement submitButton = createDomHTMLInputElement(); + // The -1 tab index value makes this element not reachable by keyboard. + final DomHTMLInputElement submitButton = createDomHTMLInputElement()..tabIndex = -1; _styleAutofillElements(submitButton, isOffScreen: true); submitButton.className = 'submitBtn'; submitButton.type = 'submit'; @@ -1130,8 +1131,8 @@ class GloballyPositionedTextEditingStrategy extends DefaultTextEditingStrategy { // only after placing it to the correct position. Hence autofill menu // does not appear on top-left of the page. // Refocus on the elements after applying the geometry. - focusedFormElement!.focus(); - activeDomElement.focus(); + focusedFormElement!.focus(preventScroll: true); + moveFocusToActiveDomElement(); } } } @@ -1157,42 +1158,20 @@ class SafariDesktopTextEditingStrategy extends DefaultTextEditingStrategy { /// /// This method is similar to the [GloballyPositionedTextEditingStrategy]. /// The only part different: this method does not call `super.placeElement()`, - /// which in current state calls `domElement.focus()`. + /// which in current state calls `domElement.focus(preventScroll: true)`. /// /// Making an extra `focus` request causes flickering in Safari. @override void placeElement() { geometry?.applyToDomElement(activeDomElement); if (hasAutofillGroup) { - // We listen to pointerdown events on the Flutter View element and programatically - // focus our inputs. However, these inputs are focused before the pointerdown - // events conclude. Thus, the browser triggers a blur event immediately after - // focusing these inputs. This causes issues with Safari Desktop's autofill - // dialog (ref: https://github.com/flutter/flutter/issues/127960). - // In order to guarantee that we only focus after the pointerdown event concludes, - // we wrap the form autofill placement and focus logic in a zero-duration Timer. - // This ensures that our input doesn't have instantaneous focus/blur events - // occur on it and fixes the autofill dialog bug as a result. - Timer(Duration.zero, () { - placeForm(); - // On Safari Desktop, when a form is focused, it opens an autofill menu - // immediately. - // Flutter framework sends `setEditableSizeAndTransform` for informing - // the engine about the location of the text field. This call may arrive - // after the first `show` call, depending on the text input widget's - // implementation. Therefore form is placed, when - // `setEditableSizeAndTransform` method is called and focus called on the - // form only after placing it to the correct position and only once after - // that. Calling focus multiple times causes flickering. - focusedFormElement!.focus(); - - // Set the last editing state if it exists, this is critical for a - // users ongoing work to continue uninterrupted when there is an update to - // the transform. - // If domElement is not focused cursor location will not be correct. - activeDomElement.focus(); - lastEditingState?.applyToDomElement(activeDomElement); - }); + placeForm(); + // Set the last editing state if it exists, this is critical for a + // users ongoing work to continue uninterrupted when there is an update to + // the transform. + // If domElement is not focused cursor location will not be correct. + moveFocusToActiveDomElement(); + lastEditingState?.applyToDomElement(activeDomElement); } } @@ -1201,7 +1180,7 @@ class SafariDesktopTextEditingStrategy extends DefaultTextEditingStrategy { if (geometry != null) { placeElement(); } - activeDomElement.focus(); + moveFocusToActiveDomElement(); } } @@ -1248,6 +1227,12 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements return domElement!; } + /// The [FlutterView] in which [activeDomElement] is contained. + EngineFlutterView? get _activeDomElementView => _viewForElement(activeDomElement); + + EngineFlutterView? _viewForElement(DomElement element) => + EnginePlatformDispatcher.instance.viewManager.findViewForElement(element); + late InputConfiguration inputConfiguration; EditingState? lastEditingState; @@ -1285,7 +1270,8 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements }) { assert(!isEnabled); - domElement = inputConfig.inputType.createDomElement(); + // The -1 tab index value makes this element not reachable by keyboard. + domElement = inputConfig.inputType.createDomElement()..tabIndex = -1; applyConfiguration(inputConfig); _setStaticStyleAttributes(activeDomElement); @@ -1363,15 +1349,16 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements subscriptions.add(DomSubscription(domDocument, 'selectionchange', handleChange)); - activeDomElement.addEventListener('beforeinput', - createDomEventListener(handleBeforeInput)); + subscriptions.add(DomSubscription(activeDomElement, 'beforeinput', + handleBeforeInput)); - addCompositionEventHandlers(activeDomElement); + if (this is! SafariDesktopTextEditingStrategy) { + // handleBlur causes Safari to reopen autofill dialogs after autofill, + // so we don't attach the listener there. + subscriptions.add(DomSubscription(activeDomElement, 'blur', handleBlur)); + } - // Refocus on the activeDomElement after blur, so that user can keep editing the - // text field. - subscriptions.add(DomSubscription(activeDomElement, 'blur', - (_) { activeDomElement.focus(); })); + addCompositionEventHandlers(activeDomElement); preventDefaultForMouseEvents(); } @@ -1422,13 +1409,12 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements // More details on `TextInput.finishAutofillContext` call. if (_appendedToForm && inputConfiguration.autofillGroup?.formElement != null) { - // Subscriptions are removed, listeners won't be triggered. - activeDomElement.blur(); _styleAutofillElements(activeDomElement, isOffScreen: true); inputConfiguration.autofillGroup?.storeForm(); + _moveFocusToFlutterView(activeDomElement, _activeDomElementView); } else { - activeDomElement.remove(); - } + _moveFocusToFlutterView(activeDomElement, _activeDomElementView, removeElement: true); + } domElement = null; } @@ -1442,7 +1428,7 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements } void placeElement() { - activeDomElement.focus(); + moveFocusToActiveDomElement(); } void placeForm() { @@ -1508,6 +1494,15 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements } } + void handleBlur(DomEvent event) { + event as DomFocusEvent; + + final DomElement? willGainFocusElement = event.relatedTarget as DomElement?; + if (willGainFocusElement == null || _viewForElement(willGainFocusElement) == _activeDomElementView) { + moveFocusToActiveDomElement(); + } + } + void maybeSendAction(DomEvent e) { if (domInstanceOfString(e, 'KeyboardEvent')) { final DomKeyboardEvent event = e as DomKeyboardEvent; @@ -1546,7 +1541,7 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements } // Re-focuses after setting editing state. - activeDomElement.focus(); + moveFocusToActiveDomElement(); } /// Prevent default behavior for mouse down, up and move. @@ -1573,6 +1568,31 @@ abstract class DefaultTextEditingStrategy with CompositionAwareMixin implements event.preventDefault(); })); } + + /// Moves the focus to the [activeDomElement]. + void moveFocusToActiveDomElement() { + activeDomElement.focus(preventScroll: true); + } + + /// Moves the focus to the [EngineFlutterView]. + /// + /// The delay gives the engine the opportunity to focus another element. + /// The delay should help prevent the keyboard from jumping when the focus goes from + /// one text field to another. + static void _moveFocusToFlutterView( + DomElement element, + EngineFlutterView? view, { + bool removeElement = false, + }) { + Timer(Duration.zero, () { + if (element == domDocument.activeElement) { + view?.dom.rootElement.focus(preventScroll: true); + } + if (removeElement) { + element.remove(); + } + }); + } } /// IOS/Safari behaviour for text editing. @@ -1606,17 +1626,6 @@ class IOSTextEditingStrategy extends GloballyPositionedTextEditingStrategy { Timer? _positionInputElementTimer; static const Duration _delayBeforePlacement = Duration(milliseconds: 100); - /// This interval between the blur subscription and callback is considered to - /// be fast. - /// - /// This is only used for iOS. The blur callback may trigger as soon as the - /// creation of the subscription. Occasionally in this case, the virtual - /// keyboard will quickly show and hide again. - /// - /// Less than this interval allows the virtual keyboard to keep showing up - /// instead of hiding rapidly. - static const Duration _blurFastCallbackInterval = Duration(milliseconds: 200); - /// Whether or not the input element can be positioned at this point in time. /// /// This is currently only used in iOS. It's set to false before focusing the @@ -1672,8 +1681,11 @@ class IOSTextEditingStrategy extends GloballyPositionedTextEditingStrategy { subscriptions.add(DomSubscription(domDocument, 'selectionchange', handleChange)); - activeDomElement.addEventListener('beforeinput', - createDomEventListener(handleBeforeInput)); + subscriptions.add(DomSubscription(activeDomElement, 'beforeinput', + handleBeforeInput)); + + subscriptions.add(DomSubscription(activeDomElement, 'blur', + handleBlur)); addCompositionEventHandlers(activeDomElement); @@ -1685,35 +1697,6 @@ class IOSTextEditingStrategy extends GloballyPositionedTextEditingStrategy { })); _addTapListener(); - - // Record start time of blur subscription. - final Stopwatch blurWatch = Stopwatch()..start(); - - // On iOS, blur is trigerred in the following cases: - // - // 1. The browser app is sent to the background (or the tab is changed). In - // this case, the window loses focus (see [windowHasFocus]), - // so we close the input connection with the framework. - // 2. The user taps on another focusable element. In this case, we refocus - // the input field and wait for the framework to manage the focus change. - // 3. The virtual keyboard is closed by tapping "done". We can't detect this - // programmatically, so we end up refocusing the input field. This is - // okay because the virtual keyboard will hide, and as soon as the user - // taps the text field again, the virtual keyboard will come up. - // 4. Safari sometimes sends a blur event immediately after activating the - // input field. In this case, we want to keep the focus on the input field. - // In order to detect this, we measure how much time has passed since the - // input field was activated. If the time is too short, we re-focus the - // input element. - subscriptions.add(DomSubscription(activeDomElement, 'blur', - (_) { - final bool isFastCallback = blurWatch.elapsed < _blurFastCallbackInterval; - if (windowHasFocus && isFastCallback) { - activeDomElement.focus(); - } else { - owner.sendTextConnectionClosedToFrameworkIfAny(); - } - })); } @override @@ -1773,7 +1756,7 @@ class IOSTextEditingStrategy extends GloballyPositionedTextEditingStrategy { @override void placeElement() { - activeDomElement.focus(); + moveFocusToActiveDomElement(); geometry?.applyToDomElement(activeDomElement); } } @@ -1825,31 +1808,20 @@ class AndroidTextEditingStrategy extends GloballyPositionedTextEditingStrategy { DomSubscription(domDocument, 'selectionchange', handleChange)); - activeDomElement.addEventListener('beforeinput', - createDomEventListener(handleBeforeInput)); + subscriptions.add(DomSubscription(activeDomElement, 'beforeinput', + handleBeforeInput)); - addCompositionEventHandlers(activeDomElement); + subscriptions.add(DomSubscription(activeDomElement, 'blur', + handleBlur)); - subscriptions.add( - DomSubscription(activeDomElement, 'blur', - (_) { - if (windowHasFocus) { - // Chrome on Android will hide the onscreen keyboard when you tap outside - // the text box. Instead, we want the framework to tell us to hide the - // keyboard via `TextInput.clearClient` or `TextInput.hide`. Therefore - // refocus as long as [windowHasFocus] is true. - activeDomElement.focus(); - } else { - owner.sendTextConnectionClosedToFrameworkIfAny(); - } - })); + addCompositionEventHandlers(activeDomElement); preventDefaultForMouseEvents(); } @override void placeElement() { - activeDomElement.focus(); + moveFocusToActiveDomElement(); geometry?.applyToDomElement(activeDomElement); } } @@ -1889,8 +1861,9 @@ class FirefoxTextEditingStrategy extends GloballyPositionedTextEditingStrategy { DomSubscription( activeDomElement, 'keydown', maybeSendAction)); - activeDomElement.addEventListener('beforeinput', - createDomEventListener(handleBeforeInput)); + subscriptions.add( + DomSubscription( + activeDomElement, 'beforeinput', handleBeforeInput)); addCompositionEventHandlers(activeDomElement); @@ -1922,32 +1895,15 @@ class FirefoxTextEditingStrategy extends GloballyPositionedTextEditingStrategy { DomSubscription( activeDomElement, 'select', handleChange)); - // Refocus on the activeDomElement after blur, so that user can keep editing the - // text field. - subscriptions.add( - DomSubscription( - activeDomElement, - 'blur', - (_) { - _postponeFocus(); - })); + subscriptions.add(DomSubscription(activeDomElement, 'blur', + handleBlur)); preventDefaultForMouseEvents(); } - void _postponeFocus() { - // Firefox does not focus on the editing element if we call the focus - // inside the blur event, therefore we postpone the focus. - // Calling focus inside a Timer for `0` milliseconds guarantee that it is - // called after blur event propagation is completed. - Timer(Duration.zero, () { - activeDomElement.focus(); - }); - } - @override void placeElement() { - activeDomElement.focus(); + moveFocusToActiveDomElement(); geometry?.applyToDomElement(activeDomElement); // Set the last editing state if it exists, this is critical for a // users ongoing work to continue uninterrupted when there is an update to diff --git a/lib/web_ui/test/engine/text_editing_test.dart b/lib/web_ui/test/engine/text_editing_test.dart index eed507d8e786d..bea5f02bf0d66 100644 --- a/lib/web_ui/test/engine/text_editing_test.dart +++ b/lib/web_ui/test/engine/text_editing_test.dart @@ -25,6 +25,9 @@ EnginePlatformDispatcher get dispatcher => EnginePlatformDispatcher.instance; DomElement get defaultTextEditingRoot => dispatcher.implicitView!.dom.textEditingHost; +DomElement get implicitViewRootElement => + dispatcher.implicitView!.dom.rootElement; + /// Add unit tests for [FirefoxTextEditingStrategy]. // TODO(mdebbar): https://github.com/flutter/flutter/issues/46891 @@ -67,13 +70,18 @@ Future testMain() async { setUpTestViewDimensions: false ); - tearDown(() { + setUp(() { + domDocument.activeElement?.blur(); + }); + + tearDown(() async { lastEditingState = null; editingDeltaState = null; lastInputAction = null; cleanTextEditingStrategy(); cleanTestFlags(); clearBackUpDomElementIfExists(); + await waitForTextStrategyStopPropagation(); }); group('$GloballyPositionedTextEditingStrategy', () { @@ -86,13 +94,16 @@ Future testMain() async { testTextEditing.configuration = singlelineConfig; }); - test('Creates element when enabled and removes it when disabled', () { + test('Creates element when enabled and removes it when disabled', () async { expect( domDocument.getElementsByTagName('input'), hasLength(0), ); - // The focus initially is on the body. - expect(domDocument.activeElement, domDocument.body); + expect( + domDocument.activeElement, + domDocument.body, + reason: 'The focus should initially be on the body', + ); expect(defaultTextEditingRoot.ownerDocument?.activeElement, domDocument.body); @@ -114,22 +125,24 @@ Future testMain() async { expect(editingStrategy!.domElement, input); expect(input.getAttribute('type'), null); + expect(input.tabIndex, -1, reason: 'The input should not be reachable by keyboard'); // Input is appended to the right point of the DOM. expect(defaultTextEditingRoot.contains(editingStrategy!.domElement), isTrue); editingStrategy!.disable(); + await waitForTextStrategyStopPropagation(); expect( defaultTextEditingRoot.querySelectorAll('input'), hasLength(0), ); - // The focus is back to the body. - expect(domDocument.activeElement, domDocument.body); + // The focus is back to the flutter view. + expect(domDocument.activeElement, implicitViewRootElement); expect(defaultTextEditingRoot.ownerDocument?.activeElement, - domDocument.body); + implicitViewRootElement); }); - test('inserts element in the correct view', () { + test('inserts element in the correct view', () async { final DomElement host = createDomElement('div'); domDocument.body!.append(host); final EngineFlutterView view = EngineFlutterView(dispatcher, host); @@ -152,6 +165,7 @@ Future testMain() async { // Cleanup. editingStrategy!.disable(); + await waitForTextStrategyStopPropagation(); expect(textEditingHost.querySelectorAll('input'), hasLength(0)); dispatcher.viewManager.unregisterView(view.viewId); view.dispose(); @@ -305,7 +319,7 @@ Future testMain() async { expect(lastInputAction, isNull); }); - test('Multi-line mode also works', () { + test('Multi-line mode also works', () async { // The textarea element is created lazily. expect(domDocument.getElementsByTagName('textarea'), hasLength(0)); editingStrategy!.enable( @@ -337,17 +351,23 @@ Future testMain() async { checkTextAreaEditingState(textarea, 'bar\nbaz', 2, 7); editingStrategy!.disable(); + + await waitForTextStrategyStopPropagation(); + // The textarea should be cleaned up. expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(0)); - // The focus is back to the body. - expect(defaultTextEditingRoot.ownerDocument?.activeElement, - domDocument.body); + + expect( + defaultTextEditingRoot.ownerDocument?.activeElement, + implicitViewRootElement, + reason: 'The focus should be back to the body', + ); // There should be no input action. expect(lastInputAction, isNull); }); - test('Same instance can be re-enabled with different config', () { + test('Same instance can be re-enabled with different config', () async { // Make sure there's nothing in the DOM yet. expect(domDocument.getElementsByTagName('input'), hasLength(0)); expect(domDocument.getElementsByTagName('textarea'), hasLength(0)); @@ -363,6 +383,7 @@ Future testMain() async { // Disable and check that all DOM elements were removed. editingStrategy!.disable(); + await waitForTextStrategyStopPropagation(); expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(0)); expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(0)); @@ -372,11 +393,13 @@ Future testMain() async { onChange: trackEditingState, onAction: trackInputAction, ); + await waitForTextStrategyStopPropagation(); expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(0)); expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(1)); // Disable again and check that all DOM elements were removed. editingStrategy!.disable(); + await waitForTextStrategyStopPropagation(); expect(defaultTextEditingRoot.querySelectorAll('input'), hasLength(0)); expect(defaultTextEditingRoot.querySelectorAll('textarea'), hasLength(0)); @@ -735,8 +758,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - checkInputEditingState(textEditing!.strategy.domElement, '', 0, 0); const MethodCall setEditingState = @@ -753,8 +774,13 @@ Future testMain() async { const MethodCall hide = MethodCall('TextInput.hide'); sendFrameworkMessage(codec.encodeMethodCall(hide)); - // Text editing should've stopped. - expect(domDocument.activeElement, domDocument.body); + await waitForTextStrategyStopPropagation(); + + expect( + domDocument.activeElement, + implicitViewRootElement, + reason: 'Text editing should have stopped', + ); // Confirm that [HybridTextEditing] didn't send any messages. expect(spy.messages, isEmpty); @@ -773,8 +799,11 @@ Future testMain() async { }); sendFrameworkMessage(codec.encodeMethodCall(setEditingState)); - // Editing shouldn't have started yet. - expect(domDocument.activeElement, domDocument.body); + expect( + domDocument.activeElement, + domDocument.body, + reason: 'Editing should not have started yet', + ); const MethodCall show = MethodCall('TextInput.show'); sendFrameworkMessage(codec.encodeMethodCall(show)); @@ -788,15 +817,19 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - checkInputEditingState( textEditing!.strategy.domElement, 'abcd', 2, 3); const MethodCall clearClient = MethodCall('TextInput.clearClient'); sendFrameworkMessage(codec.encodeMethodCall(clearClient)); - expect(domDocument.activeElement, domDocument.body); + await waitForTextStrategyStopPropagation(); + + expect( + domDocument.activeElement, + implicitViewRootElement, + reason: 'Text editing should have stopped', + ); // Confirm that [HybridTextEditing] didn't send any messages. expect(spy.messages, isEmpty); @@ -824,8 +857,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - const MethodCall setEditingState = MethodCall('TextInput.setEditingState', { 'text': 'abcd', @@ -893,9 +924,11 @@ Future testMain() async { }); sendFrameworkMessage(codec.encodeMethodCall(setEditingState)); - // Editing shouldn't have started yet. - expect(defaultTextEditingRoot.ownerDocument?.activeElement, - domDocument.body); + expect( + defaultTextEditingRoot.ownerDocument?.activeElement, + domDocument.body, + reason: 'Editing should not have started yet', + ); const MethodCall show = MethodCall('TextInput.show'); sendFrameworkMessage(codec.encodeMethodCall(show)); @@ -909,18 +942,14 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - checkInputEditingState( textEditing!.strategy.domElement, 'abcd', 2, 3); expect(textEditing!.isEditing, isTrue); - // DOM element is blurred. - textEditing!.strategy.domElement!.blur(); - // No connection close message sent. expect(spy.messages, hasLength(0)); await Future.delayed(Duration.zero); + // DOM element still keeps the focus. expect(defaultTextEditingRoot.ownerDocument?.activeElement, textEditing!.strategy.domElement); @@ -1007,8 +1036,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - checkInputEditingState( textEditing!.strategy.domElement, 'abcd', 2, 3); @@ -1065,8 +1092,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - // Form is added to DOM. expect(defaultTextEditingRoot.querySelectorAll('form'), isNotEmpty); @@ -1121,8 +1146,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - // Form is added to DOM. expect(defaultTextEditingRoot.querySelectorAll('form'), isNotEmpty); final DomHTMLFormElement formElement = @@ -1176,8 +1199,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - // Form is added to DOM. expect(defaultTextEditingRoot.querySelectorAll('form'), isNotEmpty); final DomHTMLFormElement formElement = @@ -1204,50 +1225,57 @@ Future testMain() async { expect(formsOnTheDom, hasLength(0)); }); - test('form is not placed and input is not focused until after tick on Desktop Safari', () async { - // Create a configuration with an AutofillGroup of four text fields. - final Map flutterMultiAutofillElementConfig = - createFlutterConfig('text', - autofillHint: 'username', - autofillHintsForFields: [ - 'username', - 'email', - 'name', - 'telephoneNumber' - ]); - final MethodCall setClient = MethodCall('TextInput.setClient', - [123, flutterMultiAutofillElementConfig]); - sendFrameworkMessage(codec.encodeMethodCall(setClient)); + test('Moves the focus across input elements', () async { + final List focusinEvents = []; + final DomEventListener handleFocusIn = createDomEventListener(focusinEvents.add); - const MethodCall setEditingState1 = + final MethodCall setClient1 = MethodCall( + 'TextInput.setClient', + [123, flutterSinglelineConfig], + ); + final MethodCall setClient2 = MethodCall( + 'TextInput.setClient', + [567, flutterSinglelineConfig], + ); + const MethodCall setEditingState = MethodCall('TextInput.setEditingState', { 'text': 'abcd', 'selectionBase': 2, 'selectionExtent': 3, }); - sendFrameworkMessage(codec.encodeMethodCall(setEditingState1)); - + final MethodCall setSizeAndTransform = configureSetSizeAndTransformMethodCall( + 150, + 50, + Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList(), + ); const MethodCall show = MethodCall('TextInput.show'); - sendFrameworkMessage(codec.encodeMethodCall(show)); + const MethodCall clearClient = MethodCall('TextInput.clearClient'); - final MethodCall setSizeAndTransform = - configureSetSizeAndTransformMethodCall(150, 50, - Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); + domDocument.body!.addEventListener('focusin', handleFocusIn); + sendFrameworkMessage(codec.encodeMethodCall(setClient1)); + sendFrameworkMessage(codec.encodeMethodCall(setEditingState)); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); + sendFrameworkMessage(codec.encodeMethodCall(show)); + final DomElement firstInput = textEditing!.strategy.domElement!; + expect(domDocument.activeElement, firstInput); - // Prior to tick, form should not exist and no elements should be focused. - expect(defaultTextEditingRoot.querySelectorAll('form'), isEmpty); - expect(domDocument.activeElement, domDocument.body); - - await waitForDesktopSafariFocus(); + sendFrameworkMessage(codec.encodeMethodCall(setClient2)); + sendFrameworkMessage(codec.encodeMethodCall(setEditingState)); + sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); + sendFrameworkMessage(codec.encodeMethodCall(show)); + final DomElement secondInput = textEditing!.strategy.domElement!; + expect(domDocument.activeElement, secondInput); + expect(firstInput, isNot(secondInput)); - // Form is added to DOM. - expect(defaultTextEditingRoot.querySelectorAll('form'), isNotEmpty); + sendFrameworkMessage(codec.encodeMethodCall(clearClient)); + await waitForTextStrategyStopPropagation(); + domDocument.body!.removeEventListener('focusin', handleFocusIn); - final DomHTMLInputElement inputElement = - textEditing!.strategy.domElement! as DomHTMLInputElement; - expect(domDocument.activeElement, inputElement); - }, skip: !isSafari); + expect(focusinEvents, hasLength(3)); + expect(focusinEvents[0].target, firstInput); + expect(focusinEvents[1].target, secondInput); + expect(focusinEvents[2].target, implicitViewRootElement); + }); test('setClient, setEditingState, show, setClient', () async { final MethodCall setClient = MethodCall( @@ -1262,8 +1290,11 @@ Future testMain() async { }); sendFrameworkMessage(codec.encodeMethodCall(setEditingState)); - // Editing shouldn't have started yet. - expect(domDocument.activeElement, domDocument.body); + expect( + domDocument.activeElement, + domDocument.body, + reason: 'Editing should not have started yet.', + ); const MethodCall show = MethodCall('TextInput.show'); sendFrameworkMessage(codec.encodeMethodCall(show)); @@ -1277,8 +1308,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - checkInputEditingState( textEditing!.strategy.domElement, 'abcd', 2, 3); @@ -1286,9 +1315,13 @@ Future testMain() async { 'TextInput.setClient', [567, flutterSinglelineConfig]); sendFrameworkMessage(codec.encodeMethodCall(setClient2)); - // Receiving another client via setClient should stop editing, hence - // should remove the previous active element. - expect(domDocument.activeElement, domDocument.body); + await waitForTextStrategyStopPropagation(); + + expect( + domDocument.activeElement, + implicitViewRootElement, + reason: 'Receiving another client via setClient should stop editing, hence should remove the previous active element.', + ); // Confirm that [HybridTextEditing] didn't send any messages. expect(spy.messages, isEmpty); @@ -1329,7 +1362,6 @@ Future testMain() async { }); sendFrameworkMessage(codec.encodeMethodCall(setEditingState2)); - await waitForDesktopSafariFocus(); // The second [setEditingState] should override the first one. checkInputEditingState( textEditing!.strategy.domElement, 'xyz', 0, 2); @@ -1371,7 +1403,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); // The second [setEditingState] should override the first one. checkInputEditingState( textEditing!.strategy.domElement, 'abcd', 2, 3); @@ -1442,7 +1473,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(updateSizeAndTransform)); - await waitForDesktopSafariFocus(); // Check the element still has focus. User can keep editing. expect(defaultTextEditingRoot.ownerDocument?.activeElement, textEditing!.strategy.domElement); @@ -1498,8 +1528,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - // The second [setEditingState] should override the first one. checkInputEditingState( textEditing!.strategy.domElement, 'abcd', 2, 3); @@ -1810,8 +1838,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - // Check if the selection range is correct. checkInputEditingState( textEditing!.strategy.domElement, 'xyz', 1, 2); @@ -1985,8 +2011,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - final DomHTMLInputElement input = textEditing!.strategy.domElement! as DomHTMLInputElement; @@ -2060,8 +2084,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - final DomHTMLInputElement input = textEditing!.strategy.domElement! as DomHTMLInputElement; @@ -2146,7 +2168,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); // The second [setEditingState] should override the first one. checkInputEditingState( textEditing!.strategy.domElement, 'abcd', 2, 3); @@ -2198,9 +2219,11 @@ Future testMain() async { 'TextInput.setClient', [123, flutterMultilineConfig]); sendFrameworkMessage(codec.encodeMethodCall(setClient)); - // Editing shouldn't have started yet. - expect(defaultTextEditingRoot.ownerDocument?.activeElement, - domDocument.body); + expect( + defaultTextEditingRoot.ownerDocument?.activeElement, + domDocument.body, + reason: 'Editing should have not started yet', + ); const MethodCall show = MethodCall('TextInput.show'); sendFrameworkMessage(codec.encodeMethodCall(show)); @@ -2214,8 +2237,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - final DomHTMLTextAreaElement textarea = textEditing!.strategy.domElement! as DomHTMLTextAreaElement; checkTextAreaEditingState(textarea, '', 0, 0); @@ -2283,8 +2304,13 @@ Future testMain() async { const MethodCall hide = MethodCall('TextInput.hide'); sendFrameworkMessage(codec.encodeMethodCall(hide)); - // Text editing should've stopped. - expect(domDocument.activeElement, domDocument.body); + await waitForTextStrategyStopPropagation(); + + expect( + domDocument.activeElement, + implicitViewRootElement, + reason: 'Text editing should have stopped', + ); // Confirm that [HybridTextEditing] didn't send any more messages. expect(spy.messages, isEmpty); @@ -2307,8 +2333,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - expect(textEditing!.strategy.domElement!.tagName, 'INPUT'); expect(getEditingInputMode(), 'none'); }); @@ -2330,8 +2354,6 @@ Future testMain() async { Matrix4.translationValues(10.0, 20.0, 30.0).storage.toList()); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - expect(textEditing!.strategy.domElement!.tagName, 'TEXTAREA'); expect(getEditingInputMode(), 'none'); }); @@ -2570,11 +2592,8 @@ Future testMain() async { final MethodCall setSizeAndTransform = configureSetSizeAndTransformMethodCall(10, 10, transform); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - final DomElement input = textEditing!.strategy.domElement!; - // Input is appended to the right view. expect(view.dom.textEditingHost.contains(input), isTrue); @@ -2654,8 +2673,6 @@ Future testMain() async { final MethodCall setSizeAndTransform = configureSetSizeAndTransformMethodCall(10, 10, transform); sendFrameworkMessage(codec.encodeMethodCall(setSizeAndTransform)); - await waitForDesktopSafariFocus(); - final DomElement input = textEditing!.strategy.domElement!; final DomElement form = textEditing!.configuration!.autofillGroup!.formElement; @@ -2699,8 +2716,6 @@ Future testMain() async { const MethodCall show = MethodCall('TextInput.show'); sendFrameworkMessage(codec.encodeMethodCall(show)); - await waitForDesktopSafariFocus(); - final DomElement input = textEditing!.strategy.domElement!; final DomElement form = textEditing!.configuration!.autofillGroup!.formElement; @@ -2871,6 +2886,7 @@ Future testMain() async { final DomHTMLInputElement inputElement = form.childNodes.toList()[0] as DomHTMLInputElement; expect(inputElement.type, 'submit'); + expect(inputElement.tabIndex, -1, reason: 'The input should not be reachable by keyboard'); // The submit button should have class `submitBtn`. expect(inputElement.className, 'submitBtn'); @@ -3526,6 +3542,8 @@ Future testMain() async { ); final DomHTMLElement input = editingStrategy!.activeDomElement; + expect(domDocument.activeElement, input, reason: 'the input element should be focused'); + expect(input.style.color, contains('transparent')); if (isSafari) { // macOS 13 returns different values than macOS 12. @@ -3535,7 +3553,7 @@ Future testMain() async { } else { expect(input.style.background, contains('transparent')); expect(input.style.outline, contains('none')); - expect(input.style.border, contains('none')); + expect(input.style.border, anyOf(contains('none'), contains('medium'))); } expect(input.style.backgroundColor, contains('transparent')); expect(input.style.caretColor, contains('transparent')); @@ -3739,13 +3757,9 @@ void clearForms() { formsOnTheDom.clear(); } -/// On Desktop Safari, the editing element is focused after a zero-duration timer -/// to prevent autofill popup flickering. We must wait a tick for this placement -/// before referencing these elements. -Future waitForDesktopSafariFocus() async { - if (textEditing.strategy is SafariDesktopTextEditingStrategy) { - await Future.delayed(Duration.zero); - } +/// Waits until the text strategy closes and moves the focus accordingly. +Future waitForTextStrategyStopPropagation() async { + await Future.delayed(Duration.zero); } class GlobalTextEditingStrategySpy extends GloballyPositionedTextEditingStrategy { From 40a81fc1eafe6a032991a12f1997c8f106d9f88a Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Mon, 24 Jun 2024 19:25:23 -0400 Subject: [PATCH 07/88] Roll Skia from e20c8b0bac0c to 5feca3095719 (1 revision) (#53544) https://skia.googlesource.com/skia.git/+log/e20c8b0bac0c..5feca3095719 2024-06-24 zhusida@bytedance.com Add 16bit BT2020, YCGCO color space support If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jsimmons@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index b3cda3e073606..5b2df82836b67 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'e20c8b0bac0caab082d6ed25022cb956147e98c0', + 'skia_revision': '5feca309571941ba047f1fafb77c0f28e077ac7d', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 0fc647d85023e..254e77d0a8f9f 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 4d714fdc37419022a84b674985b7bec1 +Signature: 4cbf2c9556c3c38af43729c5488fbf36 ==================================================================================================== LIBRARY: etc1 From 6991653cbe279e881de4047ed81ee7400bef5e00 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 24 Jun 2024 17:13:06 -0700 Subject: [PATCH 08/88] Bump impeller-cmake-example (#53538) - impeller-cmake: https://github.com/bdero/impeller-cmake/pull/25 - impeller-cmake-example: https://github.com/bdero/impeller-cmake-example/pull/23 --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 5b2df82836b67..ebdb167c39bd0 100644 --- a/DEPS +++ b/DEPS @@ -1009,7 +1009,7 @@ deps = { }, 'src/third_party/impeller-cmake-example': { - 'url': Var('flutter_git') + '/third_party/impeller-cmake-example.git' + '@' + 'c44e8093972c969acf171be72591e408a85fdc53', + 'url': Var('flutter_git') + '/third_party/impeller-cmake-example.git' + '@' + '9f8298ec31dcbebbf019bd487888166abf2f55e6', 'condition': 'download_impeller_cmake_example', }, From a07ba906c4fcace862ed0f4d13451356fe0bc952 Mon Sep 17 00:00:00 2001 From: "auto-submit[bot]" <98614782+auto-submit[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 01:20:29 +0000 Subject: [PATCH 09/88] Reverts "Re-re-land "Upgrade all[most] androidx dependencies to latest" (#53532)" (#53546) Reverts: flutter/engine#53532 Initiated by: gmackall Reason for reverting: This breaks apps that use plugins that use compileSdk 31, some of which we use in our postsubmit (so it blocks the tree). Original PR Author: gmackall Reviewed By: {reidbaker, matanlurey} This change reverts the following previous change: Re-re-land https://github.com/flutter/engine/pull/53001 (Reland attempt was at https://github.com/flutter/engine/pull/53462) Unblocked by https://github.com/flutter/flutter/pull/150585, but will still need a manual roll because I will need to re-generate a bunch of lockfiles. Also, https://github.com/flutter/flutter/blob/master/docs/engine/Testing-presubmit-Engine-PRs-with-the-Flutter-framework.md doesn't work (it's blocked on https://github.com/flutter/flutter/issues/149780) so I mostly just have to pray that no new issues occur in the roll. But I believe all issues that came up in the last attempt should be addressed by the above pr and by manual lockfile generation. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- DEPS | 2 +- shell/platform/android/BUILD.gn | 52 ++-- .../android/FlutterFragmentTest.java | 2 +- testing/scenario_app/android/app/build.gradle | 1 - .../scenario_app/android/app/gradle.lockfile | 228 ++++++++++++++++++ .../android/app/src/main/AndroidManifest.xml | 3 +- testing/scenario_app/android/build.gradle | 4 +- .../android/buildscript-gradle.lockfile | 150 ++++++++++++ tools/androidx/files.json | 47 ++-- .../android_embedding_bundle/build.gradle | 2 +- 10 files changed, 433 insertions(+), 58 deletions(-) create mode 100644 testing/scenario_app/android/app/gradle.lockfile create mode 100644 testing/scenario_app/android/buildscript-gradle.lockfile diff --git a/DEPS b/DEPS index ebdb167c39bd0..cc80e558f7b01 100644 --- a/DEPS +++ b/DEPS @@ -785,7 +785,7 @@ deps = { 'packages': [ { 'package': 'flutter/android/embedding_bundle', - 'version': 'last_updated:2024-06-18T12:13:41-0700' + 'version': 'last_updated:2024-06-12T14:15:49-0700' } ], 'condition': 'download_android_deps', diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index 041e75ee3fdc5..40e6912ec335f 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -353,37 +353,37 @@ android_java_sources = [ ] embedding_dependencies_jars = [ - "//third_party/android_embedding_dependencies/lib/activity-1.8.1.jar", - "//third_party/android_embedding_dependencies/lib/annotation-jvm-1.8.0.jar", - "//third_party/android_embedding_dependencies/lib/annotation-experimental-1.4.0.jar", - "//third_party/android_embedding_dependencies/lib/annotations-23.0.0.jar", + "//third_party/android_embedding_dependencies/lib/activity-1.0.0.jar", + "//third_party/android_embedding_dependencies/lib/annotation-1.2.0.jar", + "//third_party/android_embedding_dependencies/lib/annotation-experimental-1.1.0.jar", + "//third_party/android_embedding_dependencies/lib/annotations-13.0.jar", "//third_party/android_embedding_dependencies/lib/collection-1.1.0.jar", - "//third_party/android_embedding_dependencies/lib/core-1.13.1.jar", - "//third_party/android_embedding_dependencies/lib/core-1.10.3.jar", - "//third_party/android_embedding_dependencies/lib/core-common-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/core-runtime-2.2.0.jar", + "//third_party/android_embedding_dependencies/lib/core-1.6.0.jar", + "//third_party/android_embedding_dependencies/lib/core-1.8.0.jar", + "//third_party/android_embedding_dependencies/lib/core-common-2.1.0.jar", + "//third_party/android_embedding_dependencies/lib/core-runtime-2.0.0.jar", "//third_party/android_embedding_dependencies/lib/customview-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/fragment-1.7.1.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-1.8.22.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-common-1.8.22.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk7-1.8.20.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk8-1.8.20.jar", - "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-android-1.7.1.jar", - "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-core-jvm-1.7.1.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-common-2.7.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-common-java8-2.7.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-2.7.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-core-2.7.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-process-2.7.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-runtime-2.7.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-viewmodel-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/fragment-1.1.0.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-1.5.31.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-common-1.5.31.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk7-1.5.30.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk8-1.5.30.jar", + "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-android-1.5.2.jar", + "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-core-jvm-1.5.2.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-common-2.2.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-common-java8-2.2.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-2.0.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-core-2.0.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-process-2.2.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-runtime-2.2.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-viewmodel-2.1.0.jar", "//third_party/android_embedding_dependencies/lib/loader-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/savedstate-1.2.1.jar", - "//third_party/android_embedding_dependencies/lib/tracing-1.2.0.jar", + "//third_party/android_embedding_dependencies/lib/savedstate-1.0.0.jar", + "//third_party/android_embedding_dependencies/lib/tracing-1.0.0.jar", "//third_party/android_embedding_dependencies/lib/versionedparcelable-1.1.1.jar", "//third_party/android_embedding_dependencies/lib/viewpager-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/window-1.2.0.jar", - "//third_party/android_embedding_dependencies/lib/window-java-1.2.0.jar", + "//third_party/android_embedding_dependencies/lib/window-1.0.0-beta04.jar", + "//third_party/android_embedding_dependencies/lib/window-java-1.0.0-beta04.jar", ] action("check_imports") { diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java index 24d7c6ea32a5c..0c885997b9132 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java @@ -322,7 +322,7 @@ public void itDelegatesOnBackPressedWithSetFrameworkHandlesBack() { // Calling onBackPressed now will still be handled by Android (the default), // until setFrameworkHandlesBack is set to true. - activity.getOnBackPressedDispatcher().onBackPressed(); + activity.onBackPressed(); verify(mockDelegate, times(0)).onBackPressed(); // Setting setFrameworkHandlesBack to true means the delegate will receive diff --git a/testing/scenario_app/android/app/build.gradle b/testing/scenario_app/android/app/build.gradle index a03b92bdac42f..51eea659614d9 100644 --- a/testing/scenario_app/android/app/build.gradle +++ b/testing/scenario_app/android/app/build.gradle @@ -2,7 +2,6 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { - namespace = "dev.flutter.scenarios" lintOptions { abortOnError true checkAllWarnings true diff --git a/testing/scenario_app/android/app/gradle.lockfile b/testing/scenario_app/android/app/gradle.lockfile new file mode 100644 index 0000000000000..f79689a036e99 --- /dev/null +++ b/testing/scenario_app/android/app/gradle.lockfile @@ -0,0 +1,228 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation:1.0.0=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata +androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.asynclayoutinflater:asynclayoutinflater:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.cardview:cardview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout-solver:1.1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:1.1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.coordinatorlayout:coordinatorlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.documentfile:documentfile:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.drawerlayout:drawerlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.interpolator:interpolator:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-ui:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-utils:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common:2.3.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-process:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.print:print:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.recyclerview:recyclerview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.slidingpanelayout:slidingpanelayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.swiperefreshlayout:swiperefreshlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.test.espresso:espresso-core:3.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +androidx.test.espresso:espresso-idling-resource:3.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +androidx.test.ext:junit:1.1.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.test.services:storage:1.4.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.test:annotation:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.test:core:1.5.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.test:monitor:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata +androidx.test:monitor:1.6.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.test:rules:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +androidx.test:runner:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.vectordrawable:vectordrawable-animated:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.vectordrawable:vectordrawable:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.android.tools.analytics-library:protos:30.0.0=lintClassPath +com.android.tools.analytics-library:shared:30.0.0=lintClassPath +com.android.tools.analytics-library:tracker:30.0.0=lintClassPath +com.android.tools.build:aapt2-proto:4.1.0-alpha01-6193524=lintClassPath +com.android.tools.build:apksig:7.0.0=lintClassPath +com.android.tools.build:apkzlib:7.0.0=lintClassPath +com.android.tools.build:builder-model:7.0.0=lintClassPath +com.android.tools.build:builder-test-api:7.0.0=lintClassPath +com.android.tools.build:builder:7.0.0=lintClassPath +com.android.tools.build:manifest-merger:30.0.0=lintClassPath +com.android.tools.ddms:ddmlib:30.0.0=lintClassPath +com.android.tools.external.com-intellij:intellij-core:30.0.0=lintClassPath +com.android.tools.external.com-intellij:kotlin-compiler:30.0.0=lintClassPath +com.android.tools.external.org-jetbrains:uast:30.0.0=lintClassPath +com.android.tools.layoutlib:layoutlib-api:30.0.0=lintClassPath +com.android.tools.lint:lint-api:30.0.0=lintClassPath +com.android.tools.lint:lint-checks:30.0.0=lintClassPath +com.android.tools.lint:lint-gradle:30.0.0=lintClassPath +com.android.tools.lint:lint-model:30.0.0=lintClassPath +com.android.tools.lint:lint:30.0.0=lintClassPath +com.android.tools:annotations:30.0.0=lintClassPath +com.android.tools:common:30.0.0=lintClassPath +com.android.tools:dvlib:30.0.0=lintClassPath +com.android.tools:repository:30.0.0=lintClassPath +com.android.tools:sdk-common:30.0.0=lintClassPath +com.android.tools:sdklib:30.0.0=lintClassPath +com.android:signflinger:7.0.0=lintClassPath +com.android:zipflinger:7.0.0=lintClassPath +com.beust:jcommander:1.78=lintClassPath +com.github.javaparser:javaparser-core:3.17.0=lintClassPath +com.google.android.material:material:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.code.findbugs:jsr305:2.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.code.findbugs:jsr305:3.0.2=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,lintClassPath +com.google.code.gson:gson:2.8.6=lintClassPath +com.google.errorprone:error_prone_annotations:2.3.4=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath +com.google.guava:failureaccess:1.0.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath +com.google.guava:guava:30.1-android=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.google.guava:guava:30.1-jre=lintClassPath +com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath +com.google.j2objc:j2objc-annotations:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath +com.google.jimfs:jimfs:1.1=lintClassPath +com.google.protobuf:protobuf-java:3.10.0=lintClassPath +com.googlecode.json-simple:json-simple:1.1=lintClassPath +com.squareup.curtains:curtains:1.0.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:leakcanary-android-core:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:leakcanary-android-instrumentation:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:leakcanary-android-utils:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:leakcanary-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:leakcanary-object-watcher-android-androidx:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:leakcanary-object-watcher-android-support-fragments:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:leakcanary-object-watcher-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:leakcanary-object-watcher:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:plumber-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:shark-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:shark-graph:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:shark-hprof:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:shark-log:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.leakcanary:shark:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup.okio:okio:2.2.2=debugAndroidTestRuntimeClasspath +com.squareup:javawriter:2.1.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +com.squareup:javawriter:2.5.0=lintClassPath +com.sun.activation:javax.activation:1.2.0=lintClassPath +com.sun.istack:istack-commons-runtime:3.0.8=lintClassPath +com.sun.xml.fastinfoset:FastInfoset:1.2.16=lintClassPath +com.thoughtworks.qdox:qdox:1.12.1=lintClassPath +commons-codec:commons-codec:1.10=lintClassPath +commons-io:commons-io:2.4=lintClassPath +commons-logging:commons-logging:1.2=lintClassPath +info.picocli:picocli:4.5.2=lintClassPath +it.unimi.dsi:fastutil:8.4.0=lintClassPath +jakarta.activation:jakarta.activation-api:1.2.1=lintClassPath +jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=lintClassPath +javax.inject:javax.inject:1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath +jline:jline:2.14.6=lintClassPath +junit:junit:4.12=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata +junit:junit:4.13.1=lintClassPath +junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +net.java.dev.jna:jna-platform:5.6.0=lintClassPath +net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath +net.sf.jopt-simple:jopt-simple:4.9=lintClassPath +net.sf.kxml:kxml2:2.3.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath +org.apache.ant:ant-antlr:1.10.9=lintClassPath +org.apache.ant:ant-junit:1.10.9=lintClassPath +org.apache.ant:ant-launcher:1.10.9=lintClassPath +org.apache.ant:ant:1.10.9=lintClassPath +org.apache.commons:commons-compress:1.20=lintClassPath +org.apache.httpcomponents:httpclient:4.5.6=lintClassPath +org.apache.httpcomponents:httpcore:4.4.10=lintClassPath +org.apache.httpcomponents:httpmime:4.5.6=lintClassPath +org.bouncycastle:bcpkix-jdk15on:1.56=lintClassPath +org.bouncycastle:bcprov-jdk15on:1.56=lintClassPath +org.checkerframework:checker-compat-qual:2.5.5=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +org.checkerframework:checker-qual:3.5.0=lintClassPath +org.codehaus.groovy:groovy-all:3.0.7=lintClassPath +org.codehaus.groovy:groovy-ant:3.0.7=lintClassPath +org.codehaus.groovy:groovy-astbuilder:3.0.7=lintClassPath +org.codehaus.groovy:groovy-cli-picocli:3.0.7=lintClassPath +org.codehaus.groovy:groovy-console:3.0.7=lintClassPath +org.codehaus.groovy:groovy-datetime:3.0.7=lintClassPath +org.codehaus.groovy:groovy-docgenerator:3.0.7=lintClassPath +org.codehaus.groovy:groovy-groovydoc:3.0.7=lintClassPath +org.codehaus.groovy:groovy-groovysh:3.0.7=lintClassPath +org.codehaus.groovy:groovy-jmx:3.0.7=lintClassPath +org.codehaus.groovy:groovy-json:3.0.7=lintClassPath +org.codehaus.groovy:groovy-jsr223:3.0.7=lintClassPath +org.codehaus.groovy:groovy-macro:3.0.7=lintClassPath +org.codehaus.groovy:groovy-nio:3.0.7=lintClassPath +org.codehaus.groovy:groovy-servlet:3.0.7=lintClassPath +org.codehaus.groovy:groovy-sql:3.0.7=lintClassPath +org.codehaus.groovy:groovy-swing:3.0.7=lintClassPath +org.codehaus.groovy:groovy-templates:3.0.7=lintClassPath +org.codehaus.groovy:groovy-test-junit5:3.0.7=lintClassPath +org.codehaus.groovy:groovy-test:3.0.7=lintClassPath +org.codehaus.groovy:groovy-testng:3.0.7=lintClassPath +org.codehaus.groovy:groovy-xml:3.0.7=lintClassPath +org.codehaus.groovy:groovy:3.0.7=lintClassPath +org.glassfish.jaxb:jaxb-runtime:2.3.2=lintClassPath +org.glassfish.jaxb:txw2:2.3.2=lintClassPath +org.hamcrest:hamcrest-core:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,lintClassPath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.hamcrest:hamcrest-integration:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +org.hamcrest:hamcrest-library:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath +org.jacoco:org.jacoco.agent:0.8.8=androidJacocoAnt +org.jacoco:org.jacoco.ant:0.8.8=androidJacocoAnt +org.jacoco:org.jacoco.core:0.8.8=androidJacocoAnt +org.jacoco:org.jacoco.report:0.8.8=androidJacocoAnt +org.jetbrains.intellij.deps:trove4j:1.0.20181211=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath +org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath +org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.6.10=kotlinKlibCommonizerClasspath +org.jetbrains.kotlin:kotlin-reflect:1.4.32=lintClassPath +org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath +org.jetbrains.kotlin:kotlin-script-runtime:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:1.4.21=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata +org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32=lintClassPath +org.jetbrains.kotlin:kotlin-stdlib-common:1.6.10=apiDependenciesMetadata,debugApiDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,releaseApiDependenciesMetadata +org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32=lintClassPath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32=lintClassPath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:1.4.21=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata +org.jetbrains.kotlin:kotlin-stdlib:1.4.32=lintClassPath +org.jetbrains.kotlin:kotlin-stdlib:1.6.10=apiDependenciesMetadata,debugApiDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,releaseApiDependenciesMetadata +org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains:annotations:13.0=androidTestImplementationDependenciesMetadata,apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.junit.jupiter:junit-jupiter-api:5.7.0=lintClassPath +org.junit.jupiter:junit-jupiter-engine:5.7.0=lintClassPath +org.junit.platform:junit-platform-commons:1.7.0=lintClassPath +org.junit.platform:junit-platform-engine:1.7.0=lintClassPath +org.junit.platform:junit-platform-launcher:1.7.0=lintClassPath +org.junit:junit-bom:5.7.0=lintClassPath +org.jvnet.staxex:stax-ex:1.8.1=lintClassPath +org.opentest4j:opentest4j:1.2.0=lintClassPath +org.ow2.asm:asm-analysis:7.0=lintClassPath +org.ow2.asm:asm-analysis:9.2=androidJacocoAnt +org.ow2.asm:asm-commons:7.0=lintClassPath +org.ow2.asm:asm-commons:9.2=androidJacocoAnt +org.ow2.asm:asm-tree:7.0=lintClassPath +org.ow2.asm:asm-tree:9.2=androidJacocoAnt +org.ow2.asm:asm-util:7.0=lintClassPath +org.ow2.asm:asm:7.0=lintClassPath +org.ow2.asm:asm:9.2=androidJacocoAnt +org.testng:testng:7.3.0=lintClassPath +xerces:xercesImpl:2.12.0=lintClassPath +xml-apis:xml-apis:1.4.01=lintClassPath +empty=androidApis,androidJdkImage,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testFixturesApiDependenciesMetadata,testFixturesCompileOnlyDependenciesMetadata,testFixturesDebugApiDependenciesMetadata,testFixturesDebugCompileOnlyDependenciesMetadata,testFixturesDebugImplementationDependenciesMetadata,testFixturesDebugIntransitiveDependenciesMetadata,testFixturesDebugRuntimeOnlyDependenciesMetadata,testFixturesImplementationDependenciesMetadata,testFixturesIntransitiveDependenciesMetadata,testFixturesReleaseApiDependenciesMetadata,testFixturesReleaseCompileOnlyDependenciesMetadata,testFixturesReleaseImplementationDependenciesMetadata,testFixturesReleaseIntransitiveDependenciesMetadata,testFixturesReleaseRuntimeOnlyDependenciesMetadata,testFixturesRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata diff --git a/testing/scenario_app/android/app/src/main/AndroidManifest.xml b/testing/scenario_app/android/app/src/main/AndroidManifest.xml index e400c24567a89..e99d9ae8ae6b5 100644 --- a/testing/scenario_app/android/app/src/main/AndroidManifest.xml +++ b/testing/scenario_app/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + xmlns:tools="http://schemas.android.com/tools" + package="dev.flutter.scenarios"> Date: Mon, 24 Jun 2024 21:41:05 -0400 Subject: [PATCH 10/88] Roll Fuchsia Linux SDK from _6HNhJ6G59VMceKoN... to WUN7NQK04NjF9fRmf... (#53545) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/fuchsia-linux-sdk-flutter-engine Please CC jsimmons@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index cc80e558f7b01..de1b56e901cf3 100644 --- a/DEPS +++ b/DEPS @@ -979,7 +979,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/sdk/core/linux-amd64', - 'version': '_6HNhJ6G59VMceKoNUQPbjxtP50hnTcIQ7F5bsOFT_8C' + 'version': 'WUN7NQK04NjF9fRmfM16ILdIhytQAHB7O1631G4HsIEC' } ], 'condition': 'download_fuchsia_deps and not download_fuchsia_sdk', From f39b5ab11594d5e31a3aea680ee5c6e505d478cb Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Mon, 24 Jun 2024 22:15:27 -0400 Subject: [PATCH 11/88] Roll Dart SDK from c187d4b3ec88 to bb18127b2a8e (1 revision) (#53547) https://dart.googlesource.com/sdk.git/+log/c187d4b3ec88..bb18127b2a8e 2024-06-25 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-296.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jsimmons@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_dart | 4 ++-- sky/packages/sky_engine/LICENSE | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DEPS b/DEPS index de1b56e901cf3..a38c2a3711ef1 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'c187d4b3ec889b1473e9eb7a031f1a6d065770a5', + 'dart_revision': 'bb18127b2a8e1a1afd882efcc38271212b238ff3', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index 36a4c8ef54720..642aade7635f6 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: ef670c4334a44280733b82c2126aefd0 +Signature: 0e4af40f333ea146834d901da41a1124 ==================================================================================================== LIBRARY: dart @@ -4753,7 +4753,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/5df89347bddf47cb5fa829f03d19ed77dd5ec2fd +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/bb18127b2a8e1a1afd882efcc38271212b238ff3 /third_party/fallback_root_certificates/ ==================================================================================================== diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index abc923e0bf63c..4279f5dc74c2f 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/c187d4b3ec889b1473e9eb7a031f1a6d065770a5 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/bb18127b2a8e1a1afd882efcc38271212b238ff3 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From 4bb4c1c2b5a60bb42ecdfde57ff98f001cea1f64 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Mon, 24 Jun 2024 23:49:08 -0400 Subject: [PATCH 12/88] Roll Skia from 5feca3095719 to 335200e57c26 (1 revision) (#53549) https://skia.googlesource.com/skia.git/+log/5feca3095719..335200e57c26 2024-06-25 michaelludwig@google.com [graphite] Fix conic_sk_conical_grad_buf_shader signature If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jsimmons@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index a38c2a3711ef1..8971e7d745d46 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '5feca309571941ba047f1fafb77c0f28e077ac7d', + 'skia_revision': '335200e57c267f1f41b361be517721d1db6c674d', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 254e77d0a8f9f..92285e729bd83 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 4cbf2c9556c3c38af43729c5488fbf36 +Signature: 05dbb3dc9ea1593f54d5033030dfeeb4 ==================================================================================================== LIBRARY: etc1 From afa7ce19bca80d92612dbc5d88b9a2a2a3bfd076 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 02:53:24 -0400 Subject: [PATCH 13/88] Roll Dart SDK from bb18127b2a8e to b5fc85cfcf1b (1 revision) (#53552) https://dart.googlesource.com/sdk.git/+log/bb18127b2a8e..b5fc85cfcf1b 2024-06-25 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-297.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jsimmons@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- sky/packages/sky_engine/LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 8971e7d745d46..c92e9b20d4f91 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'bb18127b2a8e1a1afd882efcc38271212b238ff3', + 'dart_revision': 'b5fc85cfcf1bae20d72fc6d8c5d490ff98eead51', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index 4279f5dc74c2f..b9b68442ba058 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/bb18127b2a8e1a1afd882efcc38271212b238ff3 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/b5fc85cfcf1bae20d72fc6d8c5d490ff98eead51 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From fbd92055f3a6ec0be91c775f519baa178a6d092e Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 06:12:21 -0400 Subject: [PATCH 14/88] Roll Skia from 335200e57c26 to 3029f75db702 (2 revisions) (#53554) https://skia.googlesource.com/skia.git/+log/335200e57c26..3029f75db702 2024-06-25 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Skia Infra from e080995c5d21 to d6925c2a17cc (4 revisions) 2024-06-25 michaelludwig@google.com Fix NPE in Tagged Images slide If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index c92e9b20d4f91..558fa4d7807de 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '335200e57c267f1f41b361be517721d1db6c674d', + 'skia_revision': '3029f75db70272636f0bbf236d57499b19ebb57a', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 92285e729bd83..fc34903fc7257 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 05dbb3dc9ea1593f54d5033030dfeeb4 +Signature: e8a3423781271215a5e149d0e6e6257c ==================================================================================================== LIBRARY: etc1 From 6313b1e5afd7e256bcb78c049e539d9a07050163 Mon Sep 17 00:00:00 2001 From: Mouad Debbar Date: Tue, 25 Jun 2024 10:14:17 -0400 Subject: [PATCH 15/88] [web] Implement `AppLifecycleState.detached` as documented (#53506) Currently, we are transitioning to the `AppLifecycleState.detached` incorrectly. This is causing the framework to stop pumping frames when the app is still active and visible. This PR re-implements the transition to `AppLifecycleState.detached` as documented [here](https://api.flutter.dev/flutter/dart-ui/AppLifecycleState.html#detached) (based on whether the app has any views or not). Fixes https://github.com/flutter/flutter/issues/150636 Fixes https://github.com/flutter/flutter/issues/149417 --- .../lib/src/engine/platform_dispatcher.dart | 7 ++- .../app_lifecycle_state.dart | 35 ++++++++---- .../app_lifecycle_state_test.dart | 54 +++++++++++++++++++ 3 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 lib/web_ui/test/engine/platform_dispatcher/app_lifecycle_state_test.dart diff --git a/lib/web_ui/lib/src/engine/platform_dispatcher.dart b/lib/web_ui/lib/src/engine/platform_dispatcher.dart index 63aa5cc65f1bd..2da5356ff13d5 100644 --- a/lib/web_ui/lib/src/engine/platform_dispatcher.dart +++ b/lib/web_ui/lib/src/engine/platform_dispatcher.dart @@ -78,7 +78,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { _addFontSizeObserver(); _addLocaleChangedListener(); registerHotRestartListener(dispose); - AppLifecycleState.instance.addListener(_setAppLifecycleState); + _appLifecycleState.addListener(_setAppLifecycleState); _viewFocusBinding.init(); domDocument.body?.prepend(accessibilityPlaceholder); _onViewDisposedListener = viewManager.onViewDisposed.listen((_) { @@ -122,7 +122,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { _disconnectFontSizeObserver(); _removeLocaleChangedListener(); HighContrastSupport.instance.removeListener(_updateHighContrast); - AppLifecycleState.instance.removeListener(_setAppLifecycleState); + _appLifecycleState.removeListener(_setAppLifecycleState); _viewFocusBinding.dispose(); accessibilityPlaceholder.remove(); _onViewDisposedListener.cancel(); @@ -155,6 +155,9 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher { late final FlutterViewManager viewManager = FlutterViewManager(this); + late final AppLifecycleState _appLifecycleState = + AppLifecycleState.create(viewManager); + /// The current list of windows. @override Iterable get views => viewManager.views; diff --git a/lib/web_ui/lib/src/engine/platform_dispatcher/app_lifecycle_state.dart b/lib/web_ui/lib/src/engine/platform_dispatcher/app_lifecycle_state.dart index 138fcccab4dbf..27db846163035 100644 --- a/lib/web_ui/lib/src/engine/platform_dispatcher/app_lifecycle_state.dart +++ b/lib/web_ui/lib/src/engine/platform_dispatcher/app_lifecycle_state.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:meta/meta.dart'; import 'package:ui/ui.dart' as ui; @@ -12,7 +14,9 @@ typedef AppLifecycleStateListener = void Function(ui.AppLifecycleState state); /// Determines the [ui.AppLifecycleState]. abstract class AppLifecycleState { - static final AppLifecycleState instance = _BrowserAppLifecycleState(); + static AppLifecycleState create(FlutterViewManager viewManager) { + return _BrowserAppLifecycleState(viewManager); + } ui.AppLifecycleState get appLifecycleState => _appLifecycleState; ui.AppLifecycleState _appLifecycleState = ui.AppLifecycleState.resumed; @@ -56,28 +60,36 @@ abstract class AppLifecycleState { /// browser events. /// /// This class listens to: -/// - 'beforeunload' on [DomWindow] to detect detachment, /// - 'visibilitychange' on [DomHTMLDocument] to observe visibility changes, /// - 'focus' and 'blur' on [DomWindow] to track application focus shifts. class _BrowserAppLifecycleState extends AppLifecycleState { + _BrowserAppLifecycleState(this._viewManager); + + final FlutterViewManager _viewManager; + final List> _subscriptions = >[]; + @override void activate() { domWindow.addEventListener('focus', _focusListener); domWindow.addEventListener('blur', _blurListener); - // TODO(web): Register 'beforeunload' only if lifecycle listeners exist, to improve efficiency: https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#usage_notes - domWindow.addEventListener('beforeunload', _beforeUnloadListener); domDocument.addEventListener('visibilitychange', _visibilityChangeListener); + _subscriptions + ..add(_viewManager.onViewCreated.listen(_onViewCountChanged)) + ..add(_viewManager.onViewDisposed.listen(_onViewCountChanged)); } @override void deactivate() { domWindow.removeEventListener('focus', _focusListener); domWindow.removeEventListener('blur', _blurListener); - domWindow.removeEventListener('beforeunload', _beforeUnloadListener); domDocument.removeEventListener( 'visibilitychange', _visibilityChangeListener, ); + for (final StreamSubscription subscription in _subscriptions) { + subscription.cancel(); + } + _subscriptions.clear(); } late final DomEventListener _focusListener = @@ -90,11 +102,6 @@ class _BrowserAppLifecycleState extends AppLifecycleState { onAppLifecycleStateChange(ui.AppLifecycleState.inactive); }); - late final DomEventListener _beforeUnloadListener = - createDomEventListener((DomEvent event) { - onAppLifecycleStateChange(ui.AppLifecycleState.detached); - }); - late final DomEventListener _visibilityChangeListener = createDomEventListener((DomEvent event) { if (domDocument.visibilityState == 'visible') { @@ -103,4 +110,12 @@ class _BrowserAppLifecycleState extends AppLifecycleState { onAppLifecycleStateChange(ui.AppLifecycleState.hidden); } }); + + void _onViewCountChanged(_) { + if (_viewManager.views.isEmpty) { + onAppLifecycleStateChange(ui.AppLifecycleState.detached); + } else { + onAppLifecycleStateChange(ui.AppLifecycleState.resumed); + } + } } diff --git a/lib/web_ui/test/engine/platform_dispatcher/app_lifecycle_state_test.dart b/lib/web_ui/test/engine/platform_dispatcher/app_lifecycle_state_test.dart new file mode 100644 index 0000000000000..6e02aa6192c1c --- /dev/null +++ b/lib/web_ui/test/engine/platform_dispatcher/app_lifecycle_state_test.dart @@ -0,0 +1,54 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:test/bootstrap/browser.dart'; +import 'package:test/test.dart'; +import 'package:ui/src/engine.dart'; +import 'package:ui/ui.dart' as ui; + +void main() { + internalBootstrapBrowserTest(() => testMain); +} + +void testMain() { + group(AppLifecycleState, () { + test('listens to changes in view manager', () { + final FlutterViewManager viewManager = FlutterViewManager(EnginePlatformDispatcher.instance); + final AppLifecycleState state = AppLifecycleState.create(viewManager); + + ui.AppLifecycleState? currentState; + void listener(ui.AppLifecycleState newState) { + currentState = newState; + } + + state.addListener(listener); + + final view1 = EngineFlutterView(EnginePlatformDispatcher.instance, createDomHTMLDivElement()); + viewManager.registerView(view1); + expect(currentState, ui.AppLifecycleState.resumed); + currentState = null; + + final view2 = EngineFlutterView(EnginePlatformDispatcher.instance, createDomHTMLDivElement()); + viewManager.registerView(view2); + // The listener should not be called again. The view manager is still not empty. + expect(currentState, isNull); + + viewManager.disposeAndUnregisterView(view1.viewId); + // The listener should not be called again. The view manager is still not empty. + expect(currentState, isNull); + + viewManager.disposeAndUnregisterView(view2.viewId); + expect(currentState, ui.AppLifecycleState.detached); + currentState = null; + + final view3 = EngineFlutterView(EnginePlatformDispatcher.instance, createDomHTMLDivElement()); + viewManager.registerView(view3); + // The state should go back to `resumed` after a new view is registered. + expect(currentState, ui.AppLifecycleState.resumed); + + viewManager.dispose(); + state.removeListener(listener); + }); + }); +} From 62e0b5f9c340141f6e41e8073eee244d3968a81b Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 11:02:05 -0400 Subject: [PATCH 16/88] Roll Skia from 3029f75db702 to 5f21260470cf (2 revisions) (#53557) https://skia.googlesource.com/skia.git/+log/3029f75db702..5f21260470cf 2024-06-25 lokokung@google.com Use spontaneous mode for device lost callback in Dawn. 2024-06-25 kjlubick@google.com Update cmake to v3.29.0 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 558fa4d7807de..c1caf1092d338 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '3029f75db70272636f0bbf236d57499b19ebb57a', + 'skia_revision': '5f21260470cf4ac328c8f0b2e5b4f93e482f9207', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From f47d442c73d304f5ced0ef48e9b936b2625b25b7 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Tue, 25 Jun 2024 08:35:37 -0700 Subject: [PATCH 17/88] [impeller] Cleanup blur (#53543) This is a refactor, no functional change. We have a few issues in flight that talk about improving the blur. This attempts to clean everything up a bit to make it easier for us to change. issues: - https://github.com/flutter/flutter/issues/150713 - https://github.com/flutter/flutter/issues/150722 - https://github.com/flutter/flutter/issues/150720 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat --- .../filters/gaussian_blur_filter_contents.cc | 329 +++++++++++------- .../filters/gaussian_blur_filter_contents.h | 7 +- 2 files changed, 208 insertions(+), 128 deletions(-) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index efc56bc471372..e5d9331b964c2 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -69,6 +69,144 @@ void SetTileMode(SamplerDescriptor* descriptor, } } +Vector2 Clamp(Vector2 vec2, Scalar min, Scalar max) { + return Vector2(std::clamp(vec2.x, /*lo=*/min, /*hi=*/max), + std::clamp(vec2.y, /*lo=*/min, /*hi=*/max)); +} + +Vector2 ExtractScale(const Matrix& matrix) { + Vector2 entity_scale_x = matrix * Vector2(1.0, 0.0); + Vector2 entity_scale_y = matrix * Vector2(0.0, 1.0); + return Vector2(entity_scale_x.GetLength(), entity_scale_y.GetLength()); +} + +struct BlurInfo { + /// The scalar that is used to get from source space to unrotated local space. + Vector2 source_space_scalar; + /// Sigma when considering an entity's scale and the effect transform. + Vector2 scaled_sigma; + /// Blur radius in source pixels based on scaled_sigma. + Vector2 blur_radius; + /// The halo padding in source space. + Vector2 padding; + /// Padding in unrotated local space. + Vector2 local_padding; +}; + +/// Calculates sigma derivatives necessary for rendering or calculating +/// coverage. +BlurInfo CalculateBlurInfo(const Entity& entity, + const Matrix& effect_transform, + Vector2 sigma) { + // Source space here is scaled by the entity's transform. This is a + // requirement for text to be rendered correctly. You can think of this as + // "scaled source space" or "un-rotated local space". The entity's rotation is + // applied to the result of the blur as part of the result's transform. + const Vector2 source_space_scalar = + ExtractScale(entity.GetTransform().Basis()); + + Vector2 scaled_sigma = + (effect_transform.Basis() * Matrix::MakeScale(source_space_scalar) * // + Vector2(GaussianBlurFilterContents::ScaleSigma(sigma.x), + GaussianBlurFilterContents::ScaleSigma(sigma.y))) + .Abs(); + scaled_sigma = Clamp(scaled_sigma, 0, kMaxSigma); + Vector2 blur_radius = + Vector2(GaussianBlurFilterContents::CalculateBlurRadius(scaled_sigma.x), + GaussianBlurFilterContents::CalculateBlurRadius(scaled_sigma.y)); + Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y)); + Vector2 local_padding = + (Matrix::MakeScale(source_space_scalar) * padding).Abs(); + return { + .source_space_scalar = source_space_scalar, + .scaled_sigma = scaled_sigma, + .blur_radius = blur_radius, + .padding = padding, + .local_padding = local_padding, + }; +} + +/// Perform FilterInput::GetSnapshot with safety checks. +std::optional GetSnapshot(const std::shared_ptr& input, + const ContentContext& renderer, + const Entity& entity, + const std::optional& coverage_hint) { + int32_t mip_count = GaussianBlurFilterContents::kBlurFilterRequiredMipCount; + if (renderer.GetContext()->GetBackendType() == + Context::BackendType::kOpenGLES) { + // TODO(https://github.com/flutter/flutter/issues/141732): Implement mip map + // generation on opengles. + mip_count = 1; + } + + std::optional input_snapshot = + input->GetSnapshot("GaussianBlur", renderer, entity, + /*coverage_limit=*/coverage_hint, + /*mip_count=*/mip_count); + if (!input_snapshot.has_value()) { + return std::nullopt; + } + + // In order to avoid shimmering in downsampling step, we should have mips. + if (input_snapshot->texture->GetMipCount() <= 1) { + FML_DLOG(ERROR) << GaussianBlurFilterContents::kNoMipsError; + } + FML_DCHECK(!input_snapshot->texture->NeedsMipmapGeneration()); + + return input_snapshot; +} + +struct DownsamplePassArgs { + /// The output size of the down-sampling pass. + ISize subpass_size; + /// The UVs that will be used for drawing to the down-sampling pass. + /// This effectively is chopping out a region of the input. + Quad uvs; + /// The effective scalar of the down-sample pass. + /// This isn't usually exactly as we'd calculate because it has to be rounded + /// to integer boundaries for generating the texture for the output. + Vector2 effective_scalar; +}; + +/// Calculates info required for the down-sampling pass. +DownsamplePassArgs CalculateDownsamplePassArgs( + Vector2 scaled_sigma, + Vector2 padding, + ISize input_snapshot_size, + const std::shared_ptr& input, + const Entity& snapshot_entity) { + Scalar desired_scalar = + std::min(GaussianBlurFilterContents::CalculateScale(scaled_sigma.x), + GaussianBlurFilterContents::CalculateScale(scaled_sigma.y)); + // TODO(jonahwilliams): If desired_scalar is 1.0 and we fully acquired the + // gutter from the expanded_coverage_hint, we can skip the downsample pass. + // pass. + Vector2 downsample_scalar(desired_scalar, desired_scalar); + Rect source_rect = Rect::MakeSize(input_snapshot_size); + Rect source_rect_padded = source_rect.Expand(padding); + // TODO(gaaclarke): The padding could be removed if we know it's not needed or + // resized to account for the expanded_clip_coverage. There doesn't appear + // to be the math to make those calculations though. The following + // optimization works, but causes a shimmer as a result of + // https://github.com/flutter/flutter/issues/140193 so it isn't applied. + // + // !input_snapshot->GetCoverage()->Expand(-local_padding) + // .Contains(coverage_hint.value())) + Vector2 downsampled_size = source_rect_padded.GetSize() * downsample_scalar; + ISize subpass_size = + ISize(round(downsampled_size.x), round(downsampled_size.y)); + Vector2 effective_scalar = + Vector2(subpass_size) / source_rect_padded.GetSize(); + + Quad uvs = GaussianBlurFilterContents::CalculateUVs( + input, snapshot_entity, source_rect_padded, input_snapshot_size); + return { + .subpass_size = subpass_size, + .uvs = uvs, + .effective_scalar = effective_scalar, + }; +} + /// Makes a subpass that will render the scaled down input and add the /// transparent gutter required for the blur halo. fml::StatusOr MakeDownsampleSubpass( @@ -76,8 +214,7 @@ fml::StatusOr MakeDownsampleSubpass( const std::shared_ptr& command_buffer, std::shared_ptr input_texture, const SamplerDescriptor& sampler_descriptor, - const Quad& uvs, - const ISize& subpass_size, + const DownsamplePassArgs& pass_args, Entity::TileMode tile_mode) { ContentContext::SubpassCallback subpass_callback = [&](const ContentContext& renderer, RenderPass& pass) { @@ -95,6 +232,7 @@ fml::StatusOr MakeDownsampleSubpass( TextureFillFragmentShader::FragInfo frag_info; frag_info.alpha = 1.0; + const Quad& uvs = pass_args.uvs; BindVertices(pass, host_buffer, { {Point(0, 0), uvs[0]}, @@ -118,8 +256,9 @@ fml::StatusOr MakeDownsampleSubpass( return pass.Draw().ok(); }; - fml::StatusOr render_target = renderer.MakeSubpass( - "Gaussian Blur Filter", subpass_size, command_buffer, subpass_callback); + fml::StatusOr render_target = + renderer.MakeSubpass("Gaussian Blur Filter", pass_args.subpass_size, + command_buffer, subpass_callback); return render_target; } @@ -195,6 +334,30 @@ Rect MakeReferenceUVs(const Rect& reference, const Rect& rect) { return result.Scale(1.0f / Vector2(reference.GetSize())); } +Quad CalculateBlurUVs( + const Snapshot& input_snapshot, + const std::optional& source_expanded_coverage_hint) { + std::optional input_snapshot_coverage = input_snapshot.GetCoverage(); + Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)}; + FML_DCHECK(input_snapshot.transform.IsTranslationScaleOnly()); + if (source_expanded_coverage_hint.has_value() && + input_snapshot_coverage.has_value()) { + // Only process the uvs where the blur is happening, not the whole texture. + std::optional uvs = + MakeReferenceUVs(input_snapshot_coverage.value(), + source_expanded_coverage_hint.value()) + .Intersection(Rect::MakeSize(Size(1, 1))); + FML_DCHECK(uvs.has_value()); + if (uvs.has_value()) { + blur_uvs[0] = uvs->GetLeftTop(); + blur_uvs[1] = uvs->GetRightTop(); + blur_uvs[2] = uvs->GetLeftBottom(); + blur_uvs[3] = uvs->GetRightBottom(); + } + } + return blur_uvs; +} + int ScaleBlurRadius(Scalar radius, Scalar scalar) { return static_cast(std::round(radius * scalar)); } @@ -304,8 +467,7 @@ GaussianBlurFilterContents::GaussianBlurFilterContents( Entity::TileMode tile_mode, BlurStyle mask_blur_style, const std::shared_ptr& mask_geometry) - : sigma_x_(sigma_x), - sigma_y_(sigma_y), + : sigma_(sigma_x, sigma_y), tile_mode_(tile_mode), mask_blur_style_(mask_blur_style), mask_geometry_(mask_geometry) { @@ -346,7 +508,7 @@ Scalar GaussianBlurFilterContents::CalculateScale(Scalar sigma) { std::optional GaussianBlurFilterContents::GetFilterSourceCoverage( const Matrix& effect_transform, const Rect& output_limit) const { - Vector2 scaled_sigma = {ScaleSigma(sigma_x_), ScaleSigma(sigma_y_)}; + Vector2 scaled_sigma = {ScaleSigma(sigma_.x), ScaleSigma(sigma_.y)}; Vector2 blur_radius = {CalculateBlurRadius(scaled_sigma.x), CalculateBlurRadius(scaled_sigma.y)}; Vector3 blur_radii = @@ -354,14 +516,6 @@ std::optional GaussianBlurFilterContents::GetFilterSourceCoverage( return output_limit.Expand(Point(blur_radii.x, blur_radii.y)); } -namespace { -Vector2 ExtractScale(const Matrix& matrix) { - Vector2 entity_scale_x = matrix * Vector2(1.0, 0.0); - Vector2 entity_scale_y = matrix * Vector2(0.0, 1.0); - return Vector2(entity_scale_x.GetLength(), entity_scale_y.GetLength()); -} -} // namespace - std::optional GaussianBlurFilterContents::GetFilterCoverage( const FilterInput::Vector& inputs, const Entity& entity, @@ -374,19 +528,9 @@ std::optional GaussianBlurFilterContents::GetFilterCoverage( return {}; } - const Vector2 source_space_scalar = - ExtractScale(entity.GetTransform().Basis()); - Vector2 scaled_sigma = (Matrix::MakeScale(source_space_scalar) * - Vector2(ScaleSigma(sigma_x_), ScaleSigma(sigma_y_))) - .Abs(); - scaled_sigma.x = std::min(scaled_sigma.x, kMaxSigma); - scaled_sigma.y = std::min(scaled_sigma.y, kMaxSigma); - Vector2 blur_radius = Vector2(CalculateBlurRadius(scaled_sigma.x), - CalculateBlurRadius(scaled_sigma.y)); - Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y)); - Vector2 local_padding = - (Matrix::MakeScale(source_space_scalar) * padding).Abs(); - return input_coverage.value().Expand(Point(local_padding.x, local_padding.y)); + BlurInfo blur_info = CalculateBlurInfo(entity, effect_transform, sigma_); + return input_coverage.value().Expand( + Point(blur_info.local_padding.x, blur_info.local_padding.y)); } // A brief overview how this works: @@ -408,109 +552,57 @@ std::optional GaussianBlurFilterContents::RenderFilter( return std::nullopt; } - // Source space here is scaled by the entity's transform. This is a - // requirement for text to be rendered correctly. You can think of this as - // "scaled source space" or "un-rotated local space". The entity's rotation is - // applied to the result of the blur as part of the result's transform. - const Vector2 source_space_scalar = - ExtractScale(entity.GetTransform().Basis()); - - Vector2 scaled_sigma = - (effect_transform.Basis() * Matrix::MakeScale(source_space_scalar) * // - Vector2(ScaleSigma(sigma_x_), ScaleSigma(sigma_y_))) - .Abs(); - scaled_sigma.x = std::min(scaled_sigma.x, kMaxSigma); - scaled_sigma.y = std::min(scaled_sigma.y, kMaxSigma); - Vector2 blur_radius = Vector2(CalculateBlurRadius(scaled_sigma.x), - CalculateBlurRadius(scaled_sigma.y)); - Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y)); - Vector2 local_padding = - (Matrix::MakeScale(source_space_scalar) * padding).Abs(); + BlurInfo blur_info = CalculateBlurInfo(entity, effect_transform, sigma_); // Apply as much of the desired padding as possible from the source. This may // be ignored so must be accounted for in the downsample pass by adding a // transparent gutter. std::optional expanded_coverage_hint; if (coverage_hint.has_value()) { - expanded_coverage_hint = coverage_hint->Expand(local_padding); - } - - int32_t mip_count = kBlurFilterRequiredMipCount; - if (renderer.GetContext()->GetBackendType() == - Context::BackendType::kOpenGLES) { - // TODO(https://github.com/flutter/flutter/issues/141732): Implement mip map - // generation on opengles. - mip_count = 1; + expanded_coverage_hint = coverage_hint->Expand(blur_info.local_padding); } Entity snapshot_entity = entity.Clone(); - snapshot_entity.SetTransform(Matrix::MakeScale(source_space_scalar)); + snapshot_entity.SetTransform( + Matrix::MakeScale(blur_info.source_space_scalar)); + std::optional source_expanded_coverage_hint; if (expanded_coverage_hint.has_value()) { source_expanded_coverage_hint = expanded_coverage_hint->TransformBounds( - Matrix::MakeScale(source_space_scalar) * + Matrix::MakeScale(blur_info.source_space_scalar) * entity.GetTransform().Invert()); } - std::optional input_snapshot = - inputs[0]->GetSnapshot("GaussianBlur", renderer, snapshot_entity, - /*coverage_limit=*/source_expanded_coverage_hint, - /*mip_count=*/mip_count); + std::optional input_snapshot = GetSnapshot( + inputs[0], renderer, snapshot_entity, source_expanded_coverage_hint); if (!input_snapshot.has_value()) { return std::nullopt; } - if (scaled_sigma.x < kEhCloseEnough && scaled_sigma.y < kEhCloseEnough) { + if (blur_info.scaled_sigma.x < kEhCloseEnough && + blur_info.scaled_sigma.y < kEhCloseEnough) { Entity result = Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode()); // No blur to render. result.SetTransform(entity.GetTransform() * - Matrix::MakeScale(1.f / source_space_scalar) * + Matrix::MakeScale(1.f / blur_info.source_space_scalar) * input_snapshot->transform); return result; } - // In order to avoid shimmering in downsampling step, we should have mips. - if (input_snapshot->texture->GetMipCount() <= 1) { - FML_DLOG(ERROR) << kNoMipsError; - } - FML_DCHECK(!input_snapshot->texture->NeedsMipmapGeneration()); - - Scalar desired_scalar = - std::min(CalculateScale(scaled_sigma.x), CalculateScale(scaled_sigma.y)); - // TODO(jonahwilliams): If desired_scalar is 1.0 and we fully acquired the - // gutter from the expanded_coverage_hint, we can skip the downsample pass. - // pass. - Vector2 downsample_scalar(desired_scalar, desired_scalar); - Rect source_rect = Rect::MakeSize(input_snapshot->texture->GetSize()); - Rect source_rect_padded = source_rect.Expand(padding); - Matrix padding_snapshot_adjustment = Matrix::MakeTranslation(-padding); - // TODO(gaaclarke): The padding could be removed if we know it's not needed or - // resized to account for the expanded_clip_coverage. There doesn't appear - // to be the math to make those calculations though. The following - // optimization works, but causes a shimmer as a result of - // https://github.com/flutter/flutter/issues/140193 so it isn't applied. - // - // !input_snapshot->GetCoverage()->Expand(-local_padding) - // .Contains(coverage_hint.value())) - Vector2 downsampled_size = source_rect_padded.GetSize() * downsample_scalar; - ISize subpass_size = - ISize(round(downsampled_size.x), round(downsampled_size.y)); - Vector2 effective_scalar = - Vector2(subpass_size) / source_rect_padded.GetSize(); - - Quad uvs = CalculateUVs(inputs[0], snapshot_entity, source_rect_padded, - input_snapshot->texture->GetSize()); - std::shared_ptr command_buffer = renderer.GetContext()->CreateCommandBuffer(); if (!command_buffer) { return std::nullopt; } + DownsamplePassArgs downsample_pass_args = CalculateDownsamplePassArgs( + blur_info.scaled_sigma, blur_info.padding, + input_snapshot->texture->GetSize(), inputs[0], snapshot_entity); + fml::StatusOr pass1_out = MakeDownsampleSubpass( renderer, command_buffer, input_snapshot->texture, - input_snapshot->sampler_descriptor, uvs, subpass_size, tile_mode_); + input_snapshot->sampler_descriptor, downsample_pass_args, tile_mode_); if (!pass1_out.ok()) { return std::nullopt; @@ -519,32 +611,18 @@ std::optional GaussianBlurFilterContents::RenderFilter( Vector2 pass1_pixel_size = 1.0 / Vector2(pass1_out.value().GetRenderTargetTexture()->GetSize()); - std::optional input_snapshot_coverage = input_snapshot->GetCoverage(); - Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)}; - FML_DCHECK(input_snapshot.value().transform.IsTranslationScaleOnly()); - if (source_expanded_coverage_hint.has_value() && - input_snapshot_coverage.has_value()) { - // Only process the uvs where the blur is happening, not the whole texture. - std::optional uvs = - MakeReferenceUVs(input_snapshot_coverage.value(), - source_expanded_coverage_hint.value()) - .Intersection(Rect::MakeSize(Size(1, 1))); - FML_DCHECK(uvs.has_value()); - if (uvs.has_value()) { - blur_uvs[0] = uvs->GetLeftTop(); - blur_uvs[1] = uvs->GetRightTop(); - blur_uvs[2] = uvs->GetLeftBottom(); - blur_uvs[3] = uvs->GetRightBottom(); - } - } + Quad blur_uvs = + CalculateBlurUVs(input_snapshot.value(), source_expanded_coverage_hint); fml::StatusOr pass2_out = MakeBlurSubpass( renderer, command_buffer, /*input_pass=*/pass1_out.value(), input_snapshot->sampler_descriptor, tile_mode_, BlurParameters{ .blur_uv_offset = Point(0.0, pass1_pixel_size.y), - .blur_sigma = scaled_sigma.y * effective_scalar.y, - .blur_radius = ScaleBlurRadius(blur_radius.y, effective_scalar.y), + .blur_sigma = blur_info.scaled_sigma.y * + downsample_pass_args.effective_scalar.y, + .blur_radius = ScaleBlurRadius( + blur_info.blur_radius.y, downsample_pass_args.effective_scalar.y), .step_size = 1, }, /*destination_target=*/std::nullopt, blur_uvs); @@ -564,8 +642,10 @@ std::optional GaussianBlurFilterContents::RenderFilter( input_snapshot->sampler_descriptor, tile_mode_, BlurParameters{ .blur_uv_offset = Point(pass1_pixel_size.x, 0.0), - .blur_sigma = scaled_sigma.x * effective_scalar.x, - .blur_radius = ScaleBlurRadius(blur_radius.x, effective_scalar.x), + .blur_sigma = blur_info.scaled_sigma.x * + downsample_pass_args.effective_scalar.x, + .blur_radius = ScaleBlurRadius( + blur_info.blur_radius.x, downsample_pass_args.effective_scalar.x), .step_size = 1, }, pass3_destination, blur_uvs); @@ -593,18 +673,19 @@ std::optional GaussianBlurFilterContents::RenderFilter( Entity blur_output_entity = Entity::FromSnapshot( Snapshot{.texture = pass3_out.value().GetRenderTargetTexture(), - .transform = entity.GetTransform() * // - Matrix::MakeScale(1.f / source_space_scalar) * // - input_snapshot->transform * // - padding_snapshot_adjustment * // - Matrix::MakeScale(1 / effective_scalar), + .transform = + entity.GetTransform() * // + Matrix::MakeScale(1.f / blur_info.source_space_scalar) * // + input_snapshot->transform * // + Matrix::MakeTranslation(-blur_info.padding) * // + Matrix::MakeScale(1 / downsample_pass_args.effective_scalar), .sampler_descriptor = sampler_desc, .opacity = input_snapshot->opacity}, entity.GetBlendMode()); return ApplyBlurStyle(mask_blur_style_, entity, inputs[0], input_snapshot.value(), std::move(blur_output_entity), - mask_geometry_, source_space_scalar); + mask_geometry_, blur_info.source_space_scalar); } Scalar GaussianBlurFilterContents::CalculateBlurRadius(Scalar sigma) { diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h index 6c53cfae95a18..3c91d23e65bb0 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h @@ -56,8 +56,8 @@ class GaussianBlurFilterContents final : public FilterContents { BlurStyle mask_blur_style, const std::shared_ptr& mask_geometry); - Scalar GetSigmaX() const { return sigma_x_; } - Scalar GetSigmaY() const { return sigma_y_; } + Scalar GetSigmaX() const { return sigma_.x; } + Scalar GetSigmaY() const { return sigma_.y; } // |FilterContents| std::optional GetFilterSourceCoverage( @@ -108,8 +108,7 @@ class GaussianBlurFilterContents final : public FilterContents { const Rect& coverage, const std::optional& coverage_hint) const override; - const Scalar sigma_x_ = 0.0; - const Scalar sigma_y_ = 0.0; + const Vector2 sigma_ = Vector2(0.0, 0.0); const Entity::TileMode tile_mode_; const BlurStyle mask_blur_style_; std::shared_ptr mask_geometry_; From f66a847a9ecd20168696114b409a454b8d3ff879 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 12:24:02 -0400 Subject: [PATCH 18/88] Roll Skia from 5f21260470cf to e4e4feb97a54 (1 revision) (#53559) https://skia.googlesource.com/skia.git/+log/5f21260470cf..e4e4feb97a54 2024-06-25 nicolettep@google.com Revert "Add 16bit BT2020, YCGCO color space support" If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index c1caf1092d338..b74206b14b3e6 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '5f21260470cf4ac328c8f0b2e5b4f93e482f9207', + 'skia_revision': 'e4e4feb97a54985f15d223753e6c4bec8a626d40', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index fc34903fc7257..6bf7f61dd3490 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: e8a3423781271215a5e149d0e6e6257c +Signature: 4c1d441ade8acae524a700a4904ba032 ==================================================================================================== LIBRARY: etc1 From 8c5b4bca033a977558cf56c546ce4ee250ee0e99 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Tue, 25 Jun 2024 10:41:14 -0700 Subject: [PATCH 19/88] [DisplayList] Switch to recording DrawVertices objects by reference (#53548) The Vertices objects are already allocated in a shared object by default so copying them inline into the recording buffer is usually a waste of time rather than reusing the memory allocated for the shared object by recording a reference. Note that the shared DlVertices objects already inline all of their data so we have good data locality as it is without further copying the data into the buffer. Might help with https://github.com/flutter/flutter/issues/150513 --- display_list/benchmarking/dl_benchmarks.cc | 2 +- display_list/benchmarking/dl_complexity_gl.cc | 2 +- display_list/benchmarking/dl_complexity_gl.h | 3 +- .../benchmarking/dl_complexity_metal.cc | 2 +- .../benchmarking/dl_complexity_metal.h | 3 +- .../benchmarking/dl_complexity_unittests.cc | 2 +- display_list/display_list.cc | 3 +- display_list/display_list_unittests.cc | 34 ++++++++- display_list/dl_builder.cc | 21 +++--- display_list/dl_builder.h | 6 +- display_list/dl_canvas.h | 7 +- display_list/dl_op_receiver.h | 3 +- display_list/dl_op_records.h | 15 ++-- display_list/dl_vertices.h | 2 +- display_list/dl_vertices_unittests.cc | 72 +++++++++---------- display_list/skia/dl_sk_canvas.cc | 7 +- display_list/skia/dl_sk_canvas.h | 2 +- display_list/skia/dl_sk_conversions.cc | 2 +- display_list/skia/dl_sk_conversions.h | 9 +-- .../skia/dl_sk_conversions_unittests.cc | 4 +- display_list/skia/dl_sk_dispatcher.cc | 5 +- display_list/skia/dl_sk_dispatcher.h | 3 +- display_list/testing/dl_test_snippets.cc | 12 ++-- display_list/testing/dl_test_snippets.h | 4 +- display_list/utils/dl_receiver_utils.h | 3 +- impeller/display_list/dl_dispatcher.cc | 5 +- impeller/display_list/dl_dispatcher.h | 2 +- impeller/display_list/dl_vertices_geometry.cc | 2 +- impeller/display_list/dl_vertices_geometry.h | 2 +- lib/ui/painting/vertices.h | 2 +- shell/common/dl_op_spy.cc | 3 +- shell/common/dl_op_spy.h | 3 +- shell/common/dl_op_spy_unittests.cc | 4 +- testing/display_list_testing.cc | 2 +- testing/display_list_testing.h | 3 +- testing/mock_canvas.cc | 4 +- testing/mock_canvas.h | 2 +- 37 files changed, 143 insertions(+), 119 deletions(-) diff --git a/display_list/benchmarking/dl_benchmarks.cc b/display_list/benchmarking/dl_benchmarks.cc index d5681864901a3..16a69d504a126 100644 --- a/display_list/benchmarking/dl_benchmarks.cc +++ b/display_list/benchmarking/dl_benchmarks.cc @@ -806,7 +806,7 @@ void BM_DrawVertices(benchmark::State& state, std::shared_ptr vertices = GetTestVertices(p, radius, 50, mode, vertex_count); total_vertex_count += vertex_count; - builder.DrawVertices(vertices.get(), DlBlendMode::kSrc, paint); + builder.DrawVertices(vertices, DlBlendMode::kSrc, paint); } state.counters["VertexCount"] = total_vertex_count; diff --git a/display_list/benchmarking/dl_complexity_gl.cc b/display_list/benchmarking/dl_complexity_gl.cc index 81143c85b40dd..0f400f20c9951 100644 --- a/display_list/benchmarking/dl_complexity_gl.cc +++ b/display_list/benchmarking/dl_complexity_gl.cc @@ -494,7 +494,7 @@ void DisplayListGLComplexityCalculator::GLHelper::drawPoints( } void DisplayListGLComplexityCalculator::GLHelper::drawVertices( - const DlVertices* vertices, + const std::shared_ptr& vertices, DlBlendMode mode) { // There is currently no way for us to get the VertexMode from the SkVertices // object, but for future reference: diff --git a/display_list/benchmarking/dl_complexity_gl.h b/display_list/benchmarking/dl_complexity_gl.h index 5cb53c96c4268..119b47d2e31a1 100644 --- a/display_list/benchmarking/dl_complexity_gl.h +++ b/display_list/benchmarking/dl_complexity_gl.h @@ -57,7 +57,8 @@ class DisplayListGLComplexityCalculator void drawPoints(DlCanvas::PointMode mode, uint32_t count, const SkPoint points[]) override; - void drawVertices(const DlVertices* vertices, DlBlendMode mode) override; + void drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) override; void drawImage(const sk_sp image, const SkPoint point, DlImageSampling sampling, diff --git a/display_list/benchmarking/dl_complexity_metal.cc b/display_list/benchmarking/dl_complexity_metal.cc index a0e044093840b..20a5af86a4608 100644 --- a/display_list/benchmarking/dl_complexity_metal.cc +++ b/display_list/benchmarking/dl_complexity_metal.cc @@ -446,7 +446,7 @@ void DisplayListMetalComplexityCalculator::MetalHelper::drawPoints( } void DisplayListMetalComplexityCalculator::MetalHelper::drawVertices( - const DlVertices* vertices, + const std::shared_ptr& vertices, DlBlendMode mode) { // There is currently no way for us to get the VertexMode from the SkVertices // object, but for future reference: diff --git a/display_list/benchmarking/dl_complexity_metal.h b/display_list/benchmarking/dl_complexity_metal.h index d5a5b77007ab8..2038001a1802d 100644 --- a/display_list/benchmarking/dl_complexity_metal.h +++ b/display_list/benchmarking/dl_complexity_metal.h @@ -57,7 +57,8 @@ class DisplayListMetalComplexityCalculator void drawPoints(DlCanvas::PointMode mode, uint32_t count, const SkPoint points[]) override; - void drawVertices(const DlVertices* vertices, DlBlendMode mode) override; + void drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) override; void drawImage(const sk_sp image, const SkPoint point, DlImageSampling sampling, diff --git a/display_list/benchmarking/dl_complexity_unittests.cc b/display_list/benchmarking/dl_complexity_unittests.cc index 511ba8b1f7972..b83f8db1d21ad 100644 --- a/display_list/benchmarking/dl_complexity_unittests.cc +++ b/display_list/benchmarking/dl_complexity_unittests.cc @@ -295,7 +295,7 @@ TEST(DisplayListComplexity, DrawVertices) { auto vertices = DlVertices::Make(DlVertexMode::kTriangles, points.size(), points.data(), nullptr, nullptr); DisplayListBuilder builder; - builder.DrawVertices(vertices.get(), DlBlendMode::kSrc, DlPaint()); + builder.DrawVertices(vertices, DlBlendMode::kSrc, DlPaint()); auto display_list = builder.Build(); auto calculators = AccumulatorCalculators(); diff --git a/display_list/display_list.cc b/display_list/display_list.cc index 029e940419ed3..0937c70f1579a 100644 --- a/display_list/display_list.cc +++ b/display_list/display_list.cc @@ -234,8 +234,7 @@ void DisplayList::DisposeOps(const uint8_t* ptr, const uint8_t* end) { #undef DL_OP_DISPOSE default: - FML_DCHECK(false); - return; + FML_UNREACHABLE(); } } } diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index 5c9397d4ccd53..635d38af7c8a9 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -1155,8 +1155,7 @@ TEST_F(DisplayListTest, SingleOpsMightSupportGroupOpacityBlendMode) { RUN_TESTS2( receiver.drawPoints(PointMode::kPoints, TestPointCount, kTestPoints); , false); - RUN_TESTS2(receiver.drawVertices(TestVertices1.get(), DlBlendMode::kSrc); - , false); + RUN_TESTS2(receiver.drawVertices(kTestVertices1, DlBlendMode::kSrc);, false); RUN_TESTS(receiver.drawImage(TestImage1, {0, 0}, kLinearSampling, true);); RUN_TESTS2(receiver.drawImage(TestImage1, {0, 0}, kLinearSampling, false); , true); @@ -3270,7 +3269,7 @@ TEST_F(DisplayListTest, NopOperationsOmittedFromRecords) { builder.DrawArc({10, 10, 20, 20}, 45, 90, true, paint); SkPoint pts[] = {{10, 10}, {20, 20}}; builder.DrawPoints(PointMode::kLines, 2, pts, paint); - builder.DrawVertices(TestVertices1, DlBlendMode::kSrcOver, paint); + builder.DrawVertices(kTestVertices1, DlBlendMode::kSrcOver, paint); builder.DrawImage(TestImage1, {10, 10}, DlImageSampling::kLinear, &paint); builder.DrawImageRect(TestImage1, SkRect{0.0f, 0.0f, 10.0f, 10.0f}, @@ -4696,5 +4695,34 @@ TEST_F(DisplayListTest, ClipPathRRectNonCulling) { cull_dl->Dispatch(expector); } +TEST_F(DisplayListTest, RecordLargeVertices) { + constexpr size_t vertex_count = 2000000; + auto points = std::vector(); + points.reserve(vertex_count); + auto colors = std::vector(); + colors.reserve(vertex_count); + for (size_t i = 0; i < vertex_count; i++) { + colors.emplace_back(DlColor(-i)); + points.emplace_back(((i & 1) == 0) ? SkPoint::Make(-i, i) + : SkPoint::Make(i, i)); + } + ASSERT_EQ(points.size(), vertex_count); + ASSERT_EQ(colors.size(), vertex_count); + auto vertices = DlVertices::Make(DlVertexMode::kTriangleStrip, vertex_count, + points.data(), points.data(), colors.data()); + ASSERT_GT(vertices->size(), 1u << 24); + auto backdrop = DlBlurImageFilter::Make(5.0f, 5.0f, DlTileMode::kDecal); + + for (int i = 0; i < 1000; i++) { + DisplayListBuilder builder; + for (int j = 0; j < 16; j++) { + builder.SaveLayer(nullptr, nullptr, backdrop.get()); + builder.DrawVertices(vertices, DlBlendMode::kSrcOver, DlPaint()); + builder.Restore(); + } + auto dl = builder.Build(); + } +} + } // namespace testing } // namespace flutter diff --git a/display_list/dl_builder.cc b/display_list/dl_builder.cc index 2ed0e6e65c782..98772c0d7a3ab 100644 --- a/display_list/dl_builder.cc +++ b/display_list/dl_builder.cc @@ -42,17 +42,17 @@ static constexpr inline bool is_power_of_two(int value) { template void* DisplayListBuilder::Push(size_t pod, Args&&... args) { size_t size = SkAlignPtr(sizeof(T) + pod); - FML_DCHECK(size < (1 << 24)); + FML_CHECK(size < (1 << 24)); if (used_ + size > allocated_) { static_assert(is_power_of_two(DL_BUILDER_PAGE), "This math needs updating for non-pow2."); // Next greater multiple of DL_BUILDER_PAGE. allocated_ = (used_ + size + DL_BUILDER_PAGE) & ~(DL_BUILDER_PAGE - 1); storage_.realloc(allocated_); - FML_DCHECK(storage_.get()); + FML_CHECK(storage_.get()); memset(storage_.get() + used_, 0, allocated_ - used_); } - FML_DCHECK(used_ + size <= allocated_); + FML_CHECK(used_ + size <= allocated_); auto op = reinterpret_cast(storage_.get() + used_); used_ += size; new (op) T{std::forward(args)...}; @@ -1309,14 +1309,14 @@ void DisplayListBuilder::DrawPoints(PointMode mode, SetAttributesFromPaint(paint, FlagsForPointMode(mode)); drawPoints(mode, count, pts); } -void DisplayListBuilder::drawVertices(const DlVertices* vertices, - DlBlendMode mode) { +void DisplayListBuilder::drawVertices( + const std::shared_ptr& vertices, + DlBlendMode mode) { DisplayListAttributeFlags flags = kDrawVerticesFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect && AccumulateOpBounds(vertices->bounds(), flags)) { - void* pod = Push(vertices->size(), mode); - new (pod) DlVertices(vertices); + Push(0, vertices, mode); // DrawVertices applies its colors to the paint so we have no way // of controlling opacity using the current paint attributes. // Although, examination of the |mode| might find some predictable @@ -1334,9 +1334,10 @@ void DisplayListBuilder::drawVertices(const DlVertices* vertices, current_layer().layer_local_accumulator.record_overlapping_bounds(); } } -void DisplayListBuilder::DrawVertices(const DlVertices* vertices, - DlBlendMode mode, - const DlPaint& paint) { +void DisplayListBuilder::DrawVertices( + const std::shared_ptr& vertices, + DlBlendMode mode, + const DlPaint& paint) { SetAttributesFromPaint(paint, DisplayListOpFlags::kDrawVerticesFlags); drawVertices(vertices, mode); } diff --git a/display_list/dl_builder.h b/display_list/dl_builder.h index 438162c071949..b1a458f68eec9 100644 --- a/display_list/dl_builder.h +++ b/display_list/dl_builder.h @@ -188,10 +188,9 @@ class DisplayListBuilder final : public virtual DlCanvas, const SkPoint pts[], const DlPaint& paint) override; // |DlCanvas| - void DrawVertices(const DlVertices* vertices, + void DrawVertices(const std::shared_ptr& vertices, DlBlendMode mode, const DlPaint& paint) override; - using DlCanvas::DrawVertices; // |DlCanvas| void DrawImage(const sk_sp& image, const SkPoint point, @@ -442,7 +441,8 @@ class DisplayListBuilder final : public virtual DlCanvas, // |DlOpReceiver| void drawPoints(PointMode mode, uint32_t count, const SkPoint pts[]) override; // |DlOpReceiver| - void drawVertices(const DlVertices* vertices, DlBlendMode mode) override; + void drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) override; // |DlOpReceiver| void drawImage(const sk_sp image, diff --git a/display_list/dl_canvas.h b/display_list/dl_canvas.h index 769deb3f582e9..ab505777aeae2 100644 --- a/display_list/dl_canvas.h +++ b/display_list/dl_canvas.h @@ -157,14 +157,9 @@ class DlCanvas { uint32_t count, const SkPoint pts[], const DlPaint& paint) = 0; - virtual void DrawVertices(const DlVertices* vertices, + virtual void DrawVertices(const std::shared_ptr& vertices, DlBlendMode mode, const DlPaint& paint) = 0; - void DrawVertices(const std::shared_ptr& vertices, - DlBlendMode mode, - const DlPaint& paint) { - DrawVertices(vertices.get(), mode, paint); - } virtual void DrawImage(const sk_sp& image, const SkPoint point, DlImageSampling sampling, diff --git a/display_list/dl_op_receiver.h b/display_list/dl_op_receiver.h index 74c65e963c05b..8de5dae62c4d7 100644 --- a/display_list/dl_op_receiver.h +++ b/display_list/dl_op_receiver.h @@ -358,7 +358,8 @@ class DlOpReceiver { virtual void drawPoints(PointMode mode, uint32_t count, const SkPoint points[]) = 0; - virtual void drawVertices(const DlVertices* vertices, DlBlendMode mode) = 0; + virtual void drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) = 0; virtual void drawImage(const sk_sp image, const SkPoint point, DlImageSampling sampling, diff --git a/display_list/dl_op_records.h b/display_list/dl_op_records.h index a8cf3063bbb42..3ad6eebe8fc54 100644 --- a/display_list/dl_op_records.h +++ b/display_list/dl_op_records.h @@ -802,24 +802,19 @@ DEFINE_DRAW_POINTS_OP(Lines, kLines); DEFINE_DRAW_POINTS_OP(Polygon, kPolygon); #undef DEFINE_DRAW_POINTS_OP -// 4 byte header + 4 byte payload packs efficiently into 8 bytes -// The DlVertices object will be pod-allocated after this structure -// and can take any number of bytes so the final efficiency will -// depend on the size of the DlVertices. -// Note that the DlVertices object ends with an array of 16-bit -// indices so the alignment can be up to 6 bytes off leading to -// up to 6 bytes of overhead +// 4 byte header + 20 byte payload packs efficiently into 24 bytes struct DrawVerticesOp final : DrawOpBase { static constexpr auto kType = DisplayListOpType::kDrawVertices; - explicit DrawVerticesOp(DlBlendMode mode) : mode(mode) {} + explicit DrawVerticesOp(const std::shared_ptr& vertices, + DlBlendMode mode) + : mode(mode), vertices(vertices) {} const DlBlendMode mode; + const std::shared_ptr vertices; void dispatch(DispatchContext& ctx) const { if (op_needed(ctx)) { - const DlVertices* vertices = - reinterpret_cast(this + 1); ctx.receiver.drawVertices(vertices, mode); } } diff --git a/display_list/dl_vertices.h b/display_list/dl_vertices.h index 6f7e6443ad6b8..582c02f0bf74e 100644 --- a/display_list/dl_vertices.h +++ b/display_list/dl_vertices.h @@ -112,7 +112,7 @@ class DlVertices { Builder(DlVertexMode mode, int vertex_count, Flags flags, int index_count); /// Returns true iff the underlying object was successfully allocated. - bool is_valid() { return vertices_ != nullptr; } + bool is_valid() const { return vertices_ != nullptr; } /// @brief Copies the indicated list of points as vertices. /// diff --git a/display_list/dl_vertices_unittests.cc b/display_list/dl_vertices_unittests.cc index f30f473b1c31f..2fe46f812b7a0 100644 --- a/display_list/dl_vertices_unittests.cc +++ b/display_list/dl_vertices_unittests.cc @@ -12,7 +12,7 @@ namespace flutter { namespace testing { TEST(DisplayListVertices, MakeWithZeroAndNegativeVerticesAndIndices) { - std::shared_ptr vertices1 = DlVertices::Make( + std::shared_ptr vertices1 = DlVertices::Make( DlVertexMode::kTriangles, 0, nullptr, nullptr, nullptr, 0, nullptr); EXPECT_NE(vertices1, nullptr); EXPECT_EQ(vertices1->vertex_count(), 0); @@ -22,7 +22,7 @@ TEST(DisplayListVertices, MakeWithZeroAndNegativeVerticesAndIndices) { EXPECT_EQ(vertices1->index_count(), 0); EXPECT_EQ(vertices1->indices(), nullptr); - std::shared_ptr vertices2 = DlVertices::Make( + std::shared_ptr vertices2 = DlVertices::Make( DlVertexMode::kTriangles, -1, nullptr, nullptr, nullptr, -1, nullptr); EXPECT_NE(vertices2, nullptr); EXPECT_EQ(vertices2->vertex_count(), 0); @@ -56,7 +56,7 @@ TEST(DisplayListVertices, MakeWithTexAndColorAndIndices) { 1, 2, 0, }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, texture_coords, colors, 6, indices); ASSERT_NE(vertices, nullptr); @@ -96,7 +96,7 @@ TEST(DisplayListVertices, MakeWithTexAndColor) { DlColor::kGreen(), }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, texture_coords, colors, 6, nullptr); ASSERT_NE(vertices, nullptr); @@ -132,7 +132,7 @@ TEST(DisplayListVertices, MakeWithTexAndIndices) { 1, 2, 0, }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, texture_coords, nullptr, 6, indices); ASSERT_NE(vertices, nullptr); @@ -170,7 +170,7 @@ TEST(DisplayListVertices, MakeWithColorAndIndices) { 1, 2, 0, }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, nullptr, colors, 6, indices); ASSERT_NE(vertices, nullptr); @@ -204,7 +204,7 @@ TEST(DisplayListVertices, MakeWithTex) { SkPoint::Make(115, 120), }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, texture_coords, nullptr, 6, nullptr); ASSERT_NE(vertices, nullptr); @@ -235,7 +235,7 @@ TEST(DisplayListVertices, MakeWithColor) { DlColor::kGreen(), }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, nullptr, colors, 6, nullptr); ASSERT_NE(vertices, nullptr); @@ -265,7 +265,7 @@ TEST(DisplayListVertices, MakeWithIndices) { 1, 2, 0, }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, nullptr, nullptr, 6, indices); ASSERT_NE(vertices, nullptr); @@ -293,7 +293,7 @@ TEST(DisplayListVertices, MakeWithNoOptionalData) { SkPoint::Make(15, 20), }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, nullptr, nullptr, 6, nullptr); ASSERT_NE(vertices, nullptr); @@ -322,7 +322,7 @@ TEST(DisplayListVertices, MakeWithIndicesButZeroIndexCount) { 1, 2, 0, }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, nullptr, nullptr, 0, indices); ASSERT_NE(vertices, nullptr); @@ -351,7 +351,7 @@ TEST(DisplayListVertices, MakeWithIndicesButNegativeIndexCount) { 1, 2, 0, }; - std::shared_ptr vertices = DlVertices::Make( + std::shared_ptr vertices = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, nullptr, nullptr, -5, indices); ASSERT_NE(vertices, nullptr); @@ -464,7 +464,7 @@ TEST(DisplayListVertices, BuildWithTexAndColorAndIndices) { builder.store_texture_coordinates(texture_coords); builder.store_colors(colors); builder.store_indices(indices); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -491,11 +491,11 @@ TEST(DisplayListVertices, BuildWithTexAndColorAndIndices) { builder2.store_texture_coordinates(texture_coords); builder2.store_colors(colors); builder2.store_indices(indices); - std::shared_ptr vertices2 = builder2.build(); + std::shared_ptr vertices2 = builder2.build(); TestEquals(*vertices, *vertices2); - std::shared_ptr vertices3 = DlVertices::Make( + std::shared_ptr vertices3 = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, texture_coords, colors, 6, indices); TestEquals(*vertices, *vertices3); @@ -523,7 +523,7 @@ TEST(DisplayListVertices, BuildWithTexAndColor) { builder.store_vertices(coords); builder.store_texture_coordinates(texture_coords); builder.store_colors(colors); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -563,7 +563,7 @@ TEST(DisplayListVertices, BuildWithTexAndIndices) { builder.store_vertices(coords); builder.store_texture_coordinates(texture_coords); builder.store_indices(indices); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -605,7 +605,7 @@ TEST(DisplayListVertices, BuildWithColorAndIndices) { builder.store_vertices(coords); builder.store_colors(colors); builder.store_indices(indices); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -642,7 +642,7 @@ TEST(DisplayListVertices, BuildWithTexUsingPoints) { Builder::kHasTextureCoordinates, 0); builder.store_vertices(coords); builder.store_texture_coordinates(texture_coords); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -676,7 +676,7 @@ TEST(DisplayListVertices, BuildWithTexUsingFloats) { Builder::kHasTextureCoordinates, 0); builder.store_vertices(coords); builder.store_texture_coordinates(texture_coords); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -723,13 +723,13 @@ TEST(DisplayListVertices, BuildUsingFloatsSameAsPoints) { Builder::kHasTextureCoordinates, 0); builder_points.store_vertices(coord_points); builder_points.store_texture_coordinates(texture_coord_points); - std::shared_ptr vertices_points = builder_points.build(); + std::shared_ptr vertices_points = builder_points.build(); Builder builder_floats(DlVertexMode::kTriangles, 3, // Builder::kHasTextureCoordinates, 0); builder_floats.store_vertices(coord_floats); builder_floats.store_texture_coordinates(texture_coord_floats); - std::shared_ptr vertices_floats = builder_floats.build(); + std::shared_ptr vertices_floats = builder_floats.build(); TestEquals(*vertices_points, *vertices_floats); } @@ -750,7 +750,7 @@ TEST(DisplayListVertices, BuildWithColor) { Builder::kHasColors, 0); builder.store_vertices(coords); builder.store_colors(colors); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -782,7 +782,7 @@ TEST(DisplayListVertices, BuildWithIndices) { Builder builder(DlVertexMode::kTriangles, 3, Builder::kNone, 6); builder.store_vertices(coords); builder.store_indices(indices); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -811,7 +811,7 @@ TEST(DisplayListVertices, BuildWithNoOptionalData) { Builder builder(DlVertexMode::kTriangles, 3, Builder::kNone, 0); builder.store_vertices(coords); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -837,7 +837,7 @@ TEST(DisplayListVertices, BuildWithNegativeIndexCount) { Builder builder(DlVertexMode::kTriangles, 3, Builder::kNone, -5); builder.store_vertices(coords); - std::shared_ptr vertices = builder.build(); + std::shared_ptr vertices = builder.build(); ASSERT_NE(vertices, nullptr); ASSERT_NE(vertices->vertices(), nullptr); @@ -875,9 +875,9 @@ TEST(DisplayListVertices, TestEquals) { 1, 2, 0, }; - std::shared_ptr vertices1 = DlVertices::Make( + std::shared_ptr vertices1 = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, texture_coords, colors, 6, indices); - std::shared_ptr vertices2 = DlVertices::Make( + std::shared_ptr vertices2 = DlVertices::Make( DlVertexMode::kTriangles, 3, coords, texture_coords, colors, 6, indices); TestEquals(*vertices1, *vertices2); } @@ -930,47 +930,47 @@ TEST(DisplayListVertices, TestNotEquals) { 2, 3, 1, }; - std::shared_ptr vertices1 = DlVertices::Make( + std::shared_ptr vertices1 = DlVertices::Make( DlVertexMode::kTriangles, 4, coords, texture_coords, colors, 9, indices); { - std::shared_ptr vertices2 = + std::shared_ptr vertices2 = DlVertices::Make(DlVertexMode::kTriangleFan, 4, coords, // texture_coords, colors, 9, indices); TestNotEquals(*vertices1, *vertices2, "vertex mode differs"); } { - std::shared_ptr vertices2 = + std::shared_ptr vertices2 = DlVertices::Make(DlVertexMode::kTriangles, 3, coords, // texture_coords, colors, 9, indices); TestNotEquals(*vertices1, *vertices2, "vertex count differs"); } { - std::shared_ptr vertices2 = + std::shared_ptr vertices2 = DlVertices::Make(DlVertexMode::kTriangles, 4, wrong_coords, // texture_coords, colors, 9, indices); TestNotEquals(*vertices1, *vertices2, "vertex coordinates differ"); } { - std::shared_ptr vertices2 = + std::shared_ptr vertices2 = DlVertices::Make(DlVertexMode::kTriangles, 4, coords, // wrong_texture_coords, colors, 9, indices); TestNotEquals(*vertices1, *vertices2, "texture coordinates differ"); } { - std::shared_ptr vertices2 = + std::shared_ptr vertices2 = DlVertices::Make(DlVertexMode::kTriangles, 4, coords, // texture_coords, wrong_colors, 9, indices); TestNotEquals(*vertices1, *vertices2, "colors differ"); } { - std::shared_ptr vertices2 = + std::shared_ptr vertices2 = DlVertices::Make(DlVertexMode::kTriangles, 4, coords, // texture_coords, colors, 6, indices); TestNotEquals(*vertices1, *vertices2, "index count differs"); } { - std::shared_ptr vertices2 = + std::shared_ptr vertices2 = DlVertices::Make(DlVertexMode::kTriangles, 4, coords, // texture_coords, colors, 9, wrong_indices); TestNotEquals(*vertices1, *vertices2, "indices differ"); diff --git a/display_list/skia/dl_sk_canvas.cc b/display_list/skia/dl_sk_canvas.cc index a836360a0f088..a7334f303ec4b 100644 --- a/display_list/skia/dl_sk_canvas.cc +++ b/display_list/skia/dl_sk_canvas.cc @@ -254,9 +254,10 @@ void DlSkCanvasAdapter::DrawPoints(PointMode mode, delegate_->drawPoints(ToSk(mode), count, pts, ToStrokedSk(paint)); } -void DlSkCanvasAdapter::DrawVertices(const DlVertices* vertices, - DlBlendMode mode, - const DlPaint& paint) { +void DlSkCanvasAdapter::DrawVertices( + const std::shared_ptr& vertices, + DlBlendMode mode, + const DlPaint& paint) { delegate_->drawVertices(ToSk(vertices), ToSk(mode), ToSk(paint)); } diff --git a/display_list/skia/dl_sk_canvas.h b/display_list/skia/dl_sk_canvas.h index 9712a8acb152a..c61f3f465455e 100644 --- a/display_list/skia/dl_sk_canvas.h +++ b/display_list/skia/dl_sk_canvas.h @@ -118,7 +118,7 @@ class DlSkCanvasAdapter final : public virtual DlCanvas { uint32_t count, const SkPoint pts[], const DlPaint& paint) override; - void DrawVertices(const DlVertices* vertices, + void DrawVertices(const std::shared_ptr& vertices, DlBlendMode mode, const DlPaint& paint) override; void DrawImage(const sk_sp& image, diff --git a/display_list/skia/dl_sk_conversions.cc b/display_list/skia/dl_sk_conversions.cc index f61c3e06b2b56..a1747cfbb26bd 100644 --- a/display_list/skia/dl_sk_conversions.cc +++ b/display_list/skia/dl_sk_conversions.cc @@ -274,7 +274,7 @@ sk_sp ToSk(const DlMaskFilter* filter) { } } -sk_sp ToSk(const DlVertices* vertices) { +sk_sp ToSk(const std::shared_ptr& vertices) { const SkColor* sk_colors = reinterpret_cast(vertices->colors()); return SkVertices::MakeCopy(ToSk(vertices->mode()), vertices->vertex_count(), diff --git a/display_list/skia/dl_sk_conversions.h b/display_list/skia/dl_sk_conversions.h index 3d99401aae0a1..ebe53882c990c 100644 --- a/display_list/skia/dl_sk_conversions.h +++ b/display_list/skia/dl_sk_conversions.h @@ -114,14 +114,7 @@ inline sk_sp ToSk(const DlMaskFilter& filter) { return ToSk(&filter); } -extern sk_sp ToSk(const DlVertices* vertices); -inline sk_sp ToSk( - const std::shared_ptr& vertices) { - return ToSk(vertices.get()); -} -inline sk_sp ToSk(const DlVertices& vertices) { - return ToSk(&vertices); -} +extern sk_sp ToSk(const std::shared_ptr& vertices); } // namespace flutter diff --git a/display_list/skia/dl_sk_conversions_unittests.cc b/display_list/skia/dl_sk_conversions_unittests.cc index f5adf4d2501b0..575113b9f64ba 100644 --- a/display_list/skia/dl_sk_conversions_unittests.cc +++ b/display_list/skia/dl_sk_conversions_unittests.cc @@ -194,12 +194,12 @@ TEST(DisplayListSkConversions, BlendColorFilterModifiesTransparency) { #undef FOR_EACH_BLEND_MODE_ENUM TEST(DisplayListSkConversions, ConvertWithZeroAndNegativeVerticesAndIndices) { - std::shared_ptr vertices1 = DlVertices::Make( + std::shared_ptr vertices1 = DlVertices::Make( DlVertexMode::kTriangles, 0, nullptr, nullptr, nullptr, 0, nullptr); EXPECT_NE(vertices1, nullptr); EXPECT_NE(ToSk(vertices1), nullptr); - std::shared_ptr vertices2 = DlVertices::Make( + std::shared_ptr vertices2 = DlVertices::Make( DlVertexMode::kTriangles, -1, nullptr, nullptr, nullptr, -1, nullptr); EXPECT_NE(vertices2, nullptr); EXPECT_NE(ToSk(vertices2), nullptr); diff --git a/display_list/skia/dl_sk_dispatcher.cc b/display_list/skia/dl_sk_dispatcher.cc index 733dbd40f3cfd..84c7115fb5fa4 100644 --- a/display_list/skia/dl_sk_dispatcher.cc +++ b/display_list/skia/dl_sk_dispatcher.cc @@ -192,8 +192,9 @@ void DlSkCanvasDispatcher::drawPoints(PointMode mode, const SkPoint pts[]) { canvas_->drawPoints(ToSk(mode), count, pts, paint()); } -void DlSkCanvasDispatcher::drawVertices(const DlVertices* vertices, - DlBlendMode mode) { +void DlSkCanvasDispatcher::drawVertices( + const std::shared_ptr& vertices, + DlBlendMode mode) { canvas_->drawVertices(ToSk(vertices), ToSk(mode), paint()); } void DlSkCanvasDispatcher::drawImage(const sk_sp image, diff --git a/display_list/skia/dl_sk_dispatcher.h b/display_list/skia/dl_sk_dispatcher.h index 17cb7440a7472..ef15f8152e736 100644 --- a/display_list/skia/dl_sk_dispatcher.h +++ b/display_list/skia/dl_sk_dispatcher.h @@ -72,7 +72,8 @@ class DlSkCanvasDispatcher : public virtual DlOpReceiver, SkScalar sweep, bool useCenter) override; void drawPoints(PointMode mode, uint32_t count, const SkPoint pts[]) override; - void drawVertices(const DlVertices* vertices, DlBlendMode mode) override; + void drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) override; void drawImage(const sk_sp image, const SkPoint point, DlImageSampling sampling, diff --git a/display_list/testing/dl_test_snippets.cc b/display_list/testing/dl_test_snippets.cc index 7c360d7df2caf..e5ad4b2f365dc 100644 --- a/display_list/testing/dl_test_snippets.cc +++ b/display_list/testing/dl_test_snippets.cc @@ -680,17 +680,17 @@ std::vector CreateAllRenderingOps() { }}, {"DrawVertices", { - {1, 112, 1, + {1, 24, 1, [](DlOpReceiver& r) { - r.drawVertices(TestVertices1.get(), DlBlendMode::kSrcIn); + r.drawVertices(kTestVertices1, DlBlendMode::kSrcIn); }}, - {1, 112, 1, + {1, 24, 1, [](DlOpReceiver& r) { - r.drawVertices(TestVertices1.get(), DlBlendMode::kDstIn); + r.drawVertices(kTestVertices1, DlBlendMode::kDstIn); }}, - {1, 112, 1, + {1, 24, 1, [](DlOpReceiver& r) { - r.drawVertices(TestVertices2.get(), DlBlendMode::kSrcIn); + r.drawVertices(kTestVertices2, DlBlendMode::kSrcIn); }}, }}, {"DrawImage", diff --git a/display_list/testing/dl_test_snippets.h b/display_list/testing/dl_test_snippets.h index 0c8c97e06b195..16d740c2fb6a0 100644 --- a/display_list/testing/dl_test_snippets.h +++ b/display_list/testing/dl_test_snippets.h @@ -192,13 +192,13 @@ static const SkPath kTestPath3 = static const SkMatrix kTestMatrix1 = SkMatrix::Scale(2, 2); static const SkMatrix kTestMatrix2 = SkMatrix::RotateDeg(45); -static std::shared_ptr TestVertices1 = +static const std::shared_ptr kTestVertices1 = DlVertices::Make(DlVertexMode::kTriangles, // 3, kTestPoints, nullptr, kColors); -static std::shared_ptr TestVertices2 = +static const std::shared_ptr kTestVertices2 = DlVertices::Make(DlVertexMode::kTriangleFan, // 3, kTestPoints, diff --git a/display_list/utils/dl_receiver_utils.h b/display_list/utils/dl_receiver_utils.h index a47178a36c125..d50cb00cba057 100644 --- a/display_list/utils/dl_receiver_utils.h +++ b/display_list/utils/dl_receiver_utils.h @@ -101,7 +101,8 @@ class IgnoreDrawDispatchHelper : public virtual DlOpReceiver { void drawPoints(DlCanvas::PointMode mode, uint32_t count, const SkPoint points[]) override {} - void drawVertices(const DlVertices* vertices, DlBlendMode mode) override {} + void drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) override {} void drawImage(const sk_sp image, const SkPoint point, DlImageSampling sampling, diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index 872c74f4cf7ab..aaed5e44f647b 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -957,8 +957,9 @@ void DlDispatcherBase::drawPoints(PointMode mode, } // |flutter::DlOpReceiver| -void DlDispatcherBase::drawVertices(const flutter::DlVertices* vertices, - flutter::DlBlendMode dl_mode) { +void DlDispatcherBase::drawVertices( + const std::shared_ptr& vertices, + flutter::DlBlendMode dl_mode) { GetCanvas().DrawVertices(MakeVertices(vertices), ToBlendMode(dl_mode), paint_); } diff --git a/impeller/display_list/dl_dispatcher.h b/impeller/display_list/dl_dispatcher.h index bb2c8624e6e3e..7349ca7e4fd84 100644 --- a/impeller/display_list/dl_dispatcher.h +++ b/impeller/display_list/dl_dispatcher.h @@ -182,7 +182,7 @@ class DlDispatcherBase : public flutter::DlOpReceiver { const SkPoint points[]) override; // |flutter::DlOpReceiver| - void drawVertices(const flutter::DlVertices* vertices, + void drawVertices(const std::shared_ptr& vertices, flutter::DlBlendMode dl_mode) override; // |flutter::DlOpReceiver| diff --git a/impeller/display_list/dl_vertices_geometry.cc b/impeller/display_list/dl_vertices_geometry.cc index 279e5905700bf..6a93757f3decb 100644 --- a/impeller/display_list/dl_vertices_geometry.cc +++ b/impeller/display_list/dl_vertices_geometry.cc @@ -29,7 +29,7 @@ static VerticesGeometry::VertexMode ToVertexMode(flutter::DlVertexMode mode) { } std::shared_ptr MakeVertices( - const flutter::DlVertices* vertices) { + const std::shared_ptr& vertices) { auto bounds = ToRect(vertices->bounds()); auto mode = ToVertexMode(vertices->mode()); std::vector positions(vertices->vertex_count()); diff --git a/impeller/display_list/dl_vertices_geometry.h b/impeller/display_list/dl_vertices_geometry.h index e7502cdc83dbe..96790af408083 100644 --- a/impeller/display_list/dl_vertices_geometry.h +++ b/impeller/display_list/dl_vertices_geometry.h @@ -12,7 +12,7 @@ namespace impeller { std::shared_ptr MakeVertices( - const flutter::DlVertices* vertices); + const std::shared_ptr& vertices); } // namespace impeller diff --git a/lib/ui/painting/vertices.h b/lib/ui/painting/vertices.h index d0390dbc4ce30..6574cd8ca96c9 100644 --- a/lib/ui/painting/vertices.h +++ b/lib/ui/painting/vertices.h @@ -26,7 +26,7 @@ class Vertices : public RefCountedDartWrappable { Dart_Handle colors_handle, Dart_Handle indices_handle); - const DlVertices* vertices() const { return vertices_.get(); } + const std::shared_ptr& vertices() const { return vertices_; } void dispose(); diff --git a/shell/common/dl_op_spy.cc b/shell/common/dl_op_spy.cc index 78ce2a3ada55d..ba3b429756051 100644 --- a/shell/common/dl_op_spy.cc +++ b/shell/common/dl_op_spy.cc @@ -79,7 +79,8 @@ void DlOpSpy::drawPoints(PointMode mode, const SkPoint points[]) { did_draw_ |= will_draw_; } -void DlOpSpy::drawVertices(const DlVertices* vertices, DlBlendMode mode) { +void DlOpSpy::drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) { did_draw_ |= will_draw_; } // In theory, below drawImage methods can produce a transparent screen when a diff --git a/shell/common/dl_op_spy.h b/shell/common/dl_op_spy.h index 2eeb6e66b5c36..490e09c60f8ec 100644 --- a/shell/common/dl_op_spy.h +++ b/shell/common/dl_op_spy.h @@ -63,7 +63,8 @@ class DlOpSpy final : public virtual DlOpReceiver, void drawPoints(PointMode mode, uint32_t count, const SkPoint points[]) override; - void drawVertices(const DlVertices* vertices, DlBlendMode mode) override; + void drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) override; void drawImage(const sk_sp image, const SkPoint point, DlImageSampling sampling, diff --git a/shell/common/dl_op_spy_unittests.cc b/shell/common/dl_op_spy_unittests.cc index 90de2eed6e180..b04c6d6f176f1 100644 --- a/shell/common/dl_op_spy_unittests.cc +++ b/shell/common/dl_op_spy_unittests.cc @@ -390,7 +390,7 @@ TEST(DlOpSpy, DrawVertices) { }; auto dl_vertices = DlVertices::Make(DlVertexMode::kTriangles, 3, vertices, texture_coordinates, colors, 0); - builder.DrawVertices(dl_vertices.get(), DlBlendMode::kSrc, paint); + builder.DrawVertices(dl_vertices, DlBlendMode::kSrc, paint); sk_sp dl = builder.Build(); DlOpSpy dl_op_spy; dl->Dispatch(dl_op_spy); @@ -416,7 +416,7 @@ TEST(DlOpSpy, DrawVertices) { }; auto dl_vertices = DlVertices::Make(DlVertexMode::kTriangles, 3, vertices, texture_coordinates, colors, 0); - builder.DrawVertices(dl_vertices.get(), DlBlendMode::kSrc, paint); + builder.DrawVertices(dl_vertices, DlBlendMode::kSrc, paint); sk_sp dl = builder.Build(); DlOpSpy dl_op_spy; dl->Dispatch(dl_op_spy); diff --git a/testing/display_list_testing.cc b/testing/display_list_testing.cc index fa1c575dabe95..8cf84bc270242 100644 --- a/testing/display_list_testing.cc +++ b/testing/display_list_testing.cc @@ -823,7 +823,7 @@ void DisplayListStreamDispatcher::drawPoints(PointMode mode, out_array("points", count, points) << ");" << std::endl; } -void DisplayListStreamDispatcher::drawVertices(const DlVertices* vertices, +void DisplayListStreamDispatcher::drawVertices(const std::shared_ptr& vertices, DlBlendMode mode) { startl() << "drawVertices(" << "DlVertices(" diff --git a/testing/display_list_testing.h b/testing/display_list_testing.h index 1f65e1645e806..b710e1e22af45 100644 --- a/testing/display_list_testing.h +++ b/testing/display_list_testing.h @@ -141,7 +141,8 @@ class DisplayListStreamDispatcher final : public DlOpReceiver { void drawPoints(PointMode mode, uint32_t count, const SkPoint points[]) override; - void drawVertices(const DlVertices* vertices, DlBlendMode mode) override; + void drawVertices(const std::shared_ptr& vertices, + DlBlendMode mode) override; void drawImage(const sk_sp image, const SkPoint point, DlImageSampling sampling, diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc index 65ab1bb96f8dd..695678e23a0ee 100644 --- a/testing/mock_canvas.cc +++ b/testing/mock_canvas.cc @@ -312,7 +312,9 @@ void MockCanvas::DrawImageNine(const sk_sp& image, FML_DCHECK(false); } -void MockCanvas::DrawVertices(const DlVertices*, DlBlendMode, const DlPaint&) { +void MockCanvas::DrawVertices(const std::shared_ptr&, + DlBlendMode, + const DlPaint&) { FML_DCHECK(false); } diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h index 7d303d466a498..f15e0ec54adf2 100644 --- a/testing/mock_canvas.h +++ b/testing/mock_canvas.h @@ -242,7 +242,7 @@ class MockCanvas final : public DlCanvas { uint32_t count, const SkPoint pts[], const DlPaint& paint) override; - void DrawVertices(const DlVertices* vertices, + void DrawVertices(const std::shared_ptr& vertices, DlBlendMode mode, const DlPaint& paint) override; From a6bd8c0fa7a90d74bb797c9093ac35b27c0c2bf3 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 13:47:47 -0400 Subject: [PATCH 20/88] Roll Skia from e4e4feb97a54 to da1ea4eb0270 (4 revisions) (#53563) https://skia.googlesource.com/skia.git/+log/e4e4feb97a54..da1ea4eb0270 2024-06-25 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll Dawn from b65ac9ea6f70 to b6d4a58d3894 (87 revisions) 2024-06-25 robertphillips@google.com [graphite] Expand CombinationBuilderTest for Precompile colorfilters 2024-06-25 skia-autoroll@skia-public.iam.gserviceaccount.com Roll SK Tool from d6925c2a17cc to 6daad90c6420 2024-06-25 skia-autoroll@skia-public.iam.gserviceaccount.com Roll vulkan-deps from ff63e67e4739 to 9365edbe34f5 (12 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index b74206b14b3e6..9514773a128fd 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'e4e4feb97a54985f15d223753e6c4bec8a626d40', + 'skia_revision': 'da1ea4eb0270a9451778ea57cc6b535ae99505de', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 0e9f516ff6c3a838899baf4382c6ffb791f64ac1 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 13:47:48 -0400 Subject: [PATCH 21/88] Roll Dart SDK from b5fc85cfcf1b to 65ab2f2cf0d3 (1 revision) (#53565) https://dart.googlesource.com/sdk.git/+log/b5fc85cfcf1b..65ab2f2cf0d3 2024-06-25 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-298.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- sky/packages/sky_engine/LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 9514773a128fd..a4db67c7b5e1f 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'b5fc85cfcf1bae20d72fc6d8c5d490ff98eead51', + 'dart_revision': '65ab2f2cf0d32dfb966bc1713bac46a2fad3d7f7', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index b9b68442ba058..6796ba30943be 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/b5fc85cfcf1bae20d72fc6d8c5d490ff98eead51 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/65ab2f2cf0d32dfb966bc1713bac46a2fad3d7f7 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From ee1884c88383b0d09d0f25fa3bb5cac2ae8bacce Mon Sep 17 00:00:00 2001 From: Jason Parrott Date: Wed, 26 Jun 2024 02:59:24 +0900 Subject: [PATCH 22/88] fix: web canvaskit fragment shaders were not using updated uniform values (#53246) This fixes an issue where in CanvasKit builds, uniforms set in setFloat function in the Paint class don't get updated after the initial render. For example, like in the issue linked below, having a shader that animates a value over time and you want to reuse the Paint object that the shader is set to. I'm no expert with CanvasKit nor with the Flutter Engine, but from what I could tell it seemed that the uniforms were only being sent to Skia on creation of the shader via _makeEffect. However, any uniforms set afterwords were just stored in a local dart-side List and forgotten about. This PR changes the List to use a WASM backed SkFloat32List to keep the references to the uniforms linked to dart-side. fixes https://github.com/flutter/flutter/issues/149800 --- .../src/engine/canvaskit/canvaskit_api.dart | 4 ++-- .../lib/src/engine/canvaskit/painting.dart | 7 ++++--- lib/web_ui/skwasm/shaders.cpp | 5 +++-- .../test/canvaskit/canvaskit_api_test.dart | 16 ++++++++++++--- lib/web_ui/test/ui/fragment_shader_test.dart | 20 +++++++++++++++++++ 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart index c0284632069d1..c41da41b36aac 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart @@ -3617,13 +3617,13 @@ SkRuntimeEffect? MakeRuntimeEffect(String program) => extension SkSkRuntimeEffectExtension on SkRuntimeEffect { @JS('makeShader') external SkShader? _makeShader(JSAny uniforms); - SkShader? makeShader(List uniforms) => + SkShader? makeShader(SkFloat32List uniforms) => _makeShader(uniforms.toJSAnyShallow); @JS('makeShaderWithChildren') external SkShader? _makeShaderWithChildren(JSAny uniforms, JSAny children); SkShader? makeShaderWithChildren( - List uniforms, List children) => + SkFloat32List uniforms, List children) => _makeShaderWithChildren(uniforms.toJSAnyShallow, children.toJSAnyShallow); } diff --git a/lib/web_ui/lib/src/engine/canvaskit/painting.dart b/lib/web_ui/lib/src/engine/canvaskit/painting.dart index 3bd9f79968edf..80a811540fd42 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/painting.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/painting.dart @@ -420,14 +420,14 @@ class CkFragmentProgram implements ui.FragmentProgram { class CkFragmentShader implements ui.FragmentShader, CkShader { CkFragmentShader(this.name, this.effect, int floatCount, int textureCount) - : floats = List.filled(floatCount + textureCount * 2, 0), + : floats = mallocFloat32List(floatCount + textureCount * 2), samplers = List.filled(textureCount, null), lastFloatIndex = floatCount; final String name; final SkRuntimeEffect effect; final int lastFloatIndex; - final List floats; + final SkFloat32List floats; final List samplers; @visibleForTesting @@ -454,7 +454,7 @@ class CkFragmentShader implements ui.FragmentShader, CkShader { @override void setFloat(int index, double value) { assert(!_debugDisposed, 'FragmentShader has been disposed of.'); - floats[index] = value; + floats.toTypedArray()[index] = value; } @override @@ -476,6 +476,7 @@ class CkFragmentShader implements ui.FragmentShader, CkShader { }()); ref?.dispose(); ref = null; + free(floats); } bool _debugDisposed = false; diff --git a/lib/web_ui/skwasm/shaders.cpp b/lib/web_ui/skwasm/shaders.cpp index d7f7d36825e9d..18e154747050a 100644 --- a/lib/web_ui/skwasm/shaders.cpp +++ b/lib/web_ui/skwasm/shaders.cpp @@ -130,9 +130,10 @@ SKWASM_EXPORT SkShader* shader_createRuntimeEffectShader( for (size_t i = 0; i < childCount; i++) { childPointers.emplace_back(sk_ref_sp(children[i])); } + return runtimeEffect - ->makeShader(SkData::MakeWithCopy(uniforms->data(), uniforms->size()), - childPointers.data(), childCount, nullptr) + ->makeShader(sk_ref_sp(uniforms), childPointers.data(), + childCount, nullptr) .release(); } diff --git a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart index b799fa966319b..5ed14398853e0 100644 --- a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart +++ b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart @@ -366,11 +366,13 @@ half4 main(vec2 fragCoord) { final SkRuntimeEffect? invalidEffect = MakeRuntimeEffect(kInvalidSkSlProgram); expect(invalidEffect, isNull); - final SkShader? shader = effect!.makeShader([]); + final SkFloat32List emptyUniforms = mallocFloat32List(0); + final SkShader? shader = effect!.makeShader(emptyUniforms); expect(shader, isNotNull); // mismatched uniforms returns null. - final SkShader? invalidShader = effect.makeShader([1]); + final SkFloat32List mismatchedUniforms = mallocFloat32List(1); + final SkShader? invalidShader = effect.makeShader(mismatchedUniforms); expect(invalidShader, isNull); @@ -382,8 +384,16 @@ return u_color; } '''; + final SkFloat32List uniforms = mallocFloat32List(4); + final uniformData = uniforms.toTypedArray(); + + uniformData[0] = 1.0; + uniformData[1] = 0.0; + uniformData[2] = 0.0; + uniformData[3] = 1.0; + final SkShader? shaderWithUniform = MakeRuntimeEffect(kSkSlProgramWithUniforms) - !.makeShader([1.0, 0.0, 0.0, 1.0]); + !.makeShader(uniforms); expect(shaderWithUniform, isNotNull); }); diff --git a/lib/web_ui/test/ui/fragment_shader_test.dart b/lib/web_ui/test/ui/fragment_shader_test.dart index 7e74d152ecbe5..307989fef528e 100644 --- a/lib/web_ui/test/ui/fragment_shader_test.dart +++ b/lib/web_ui/test/ui/fragment_shader_test.dart @@ -82,5 +82,25 @@ Future testMain() async { // Make sure we can reuse the shader object with a new uniform value. shader.setFloat(0, 25.0); await drawCircle('fragment_shader_voronoi_tile25px.png'); + + // Test reusing a Paint object with the same shader. + final ui.Paint reusablePaint = ui.Paint()..shader = shader; + + Future drawCircleReusePaint(String goldenFilename) async { + final ui.PictureRecorder recorder = ui.PictureRecorder(); + final ui.Canvas canvas = ui.Canvas(recorder, region); + canvas.drawCircle(const ui.Offset(150, 150), 100, reusablePaint); + + await drawPictureUsingCurrentRenderer(recorder.endRecording()); + + await matchGoldenFile(goldenFilename, region: region); + } + + shader.setFloat(0, 10.0); + await drawCircleReusePaint('fragment_shader_voronoi_tile10px_reuse_paint.png'); + + // Make sure we can reuse the shader object with a new uniform value and the same Paint object. + shader.setFloat(0, 25.0); + await drawCircleReusePaint('fragment_shader_voronoi_tile25px_reuse_paint.png'); }, skip: isHtml); // Fragment shaders are not supported by the HTML renderer. } From 94023d711db3f950a235fd84a80a3dde4dd86338 Mon Sep 17 00:00:00 2001 From: Jackson Gardner Date: Tue, 25 Jun 2024 11:11:11 -0700 Subject: [PATCH 23/88] [skwasm] Fixes for getting pixels from an image. (#53561) There were two issues here: 1) We have to stop using the emscripten thread scheduling APIs, as they can be invoked out of order from the rest of the messages that are posted. In some cases, out of order message handling can cause the request for reading pixels in an image to be serviced before some of the texture sources have been transfered to the web worker. 2) Skia's `readPixels` fails if there is is a lazy picture image made from a picture that contains a lazy texture image. The pertinent bug is here: https://g-issues.skia.org/issues/349201915 To work around the Skia bug, we just render the image itself onto our scratch canvas and pull the pixels out with `glReadPixels`. This fixes https://github.com/flutter/flutter/issues/141326 --- lib/web_ui/skwasm/library_skwasm_support.js | 47 +++++++++ lib/web_ui/skwasm/skwasm_support.h | 15 ++- lib/web_ui/skwasm/surface.cpp | 101 ++++++++++++-------- lib/web_ui/skwasm/surface.h | 34 ++----- lib/web_ui/skwasm/wrappers.h | 2 + lib/web_ui/test/ui/image_golden_test.dart | 3 + 6 files changed, 133 insertions(+), 69 deletions(-) diff --git a/lib/web_ui/skwasm/library_skwasm_support.js b/lib/web_ui/skwasm/library_skwasm_support.js index 5d3b660016c6c..61e8b47179f54 100644 --- a/lib/web_ui/skwasm/library_skwasm_support.js +++ b/lib/web_ui/skwasm/library_skwasm_support.js @@ -72,6 +72,24 @@ mergeInto(LibraryManager.library, { } associatedObjectsMap.delete(pointer); return; + case 'disposeSurface': + _surface_dispose(data.surface); + return; + case 'rasterizeImage': + _surface_rasterizeImageOnWorker( + data.surface, + data.image, + data.format, + data.callbackId, + ); + return; + case 'onRasterizeComplete': + _surface_onRasterizeComplete( + data.surface, + data.data, + data.callbackId, + ); + return; default: console.warn(`unrecognized skwasm message: ${skwasmMessage}`); } @@ -153,6 +171,29 @@ mergeInto(LibraryManager.library, { pointer, }); }; + _skwasm_dispatchDisposeSurface = function(threadId, surface) { + PThread.pthreads[threadId].postMessage({ + skwasmMessage: 'disposeSurface', + surface, + }); + } + _skwasm_dispatchRasterizeImage = function(threadId, surface, image, format, callbackId) { + PThread.pthreads[threadId].postMessage({ + skwasmMessage: 'rasterizeImage', + surface, + image, + format, + callbackId, + }); + } + _skwasm_postRasterizeResult = function(surface, data, callbackId) { + postMessage({ + skwasmMessage: 'onRasterizeComplete', + surface, + data, + callbackId, + }); + } }, skwasm_setAssociatedObjectOnThread: function () {}, skwasm_setAssociatedObjectOnThread__deps: ['$skwasm_support_setup'], @@ -176,5 +217,11 @@ mergeInto(LibraryManager.library, { skwasm_resolveAndPostImages__deps: ['$skwasm_support_setup'], skwasm_createGlTextureFromTextureSource: function () {}, skwasm_createGlTextureFromTextureSource__deps: ['$skwasm_support_setup'], + skwasm_dispatchDisposeSurface: function() {}, + skwasm_dispatchDisposeSurface__deps: ['$skwasm_support_setup'], + skwasm_dispatchRasterizeImage: function() {}, + skwasm_dispatchRasterizeImage__deps: ['$skwasm_support_setup'], + skwasm_postRasterizeResult: function() {}, + skwasm_postRasterizeResult__deps: ['$skwasm_support_setup'], }); \ No newline at end of file diff --git a/lib/web_ui/skwasm/skwasm_support.h b/lib/web_ui/skwasm/skwasm_support.h index c588ab8efd642..a77bd7726aa5f 100644 --- a/lib/web_ui/skwasm/skwasm_support.h +++ b/lib/web_ui/skwasm/skwasm_support.h @@ -7,12 +7,9 @@ #include #include +#include "surface.h" #include "third_party/skia/include/core/SkPicture.h" -namespace Skwasm { -class Surface; -} - using SkwasmObject = __externref_t; extern "C" { @@ -43,6 +40,16 @@ extern unsigned int skwasm_createGlTextureFromTextureSource( SkwasmObject textureSource, int width, int height); +extern void skwasm_dispatchDisposeSurface(unsigned long threadId, + Skwasm::Surface* surface); +extern void skwasm_dispatchRasterizeImage(unsigned long threadId, + Skwasm::Surface* surface, + SkImage* image, + Skwasm::ImageByteFormat format, + uint32_t callbackId); +extern void skwasm_postRasterizeResult(Skwasm::Surface* surface, + SkData* data, + uint32_t callbackId); } #endif // FLUTTER_LIB_WEB_UI_SKWASM_SKWASM_SUPPORT_H_ diff --git a/lib/web_ui/skwasm/surface.cpp b/lib/web_ui/skwasm/surface.cpp index c671c44ceb8c1..13523e0ea72c5 100644 --- a/lib/web_ui/skwasm/surface.cpp +++ b/lib/web_ui/skwasm/surface.cpp @@ -5,6 +5,7 @@ #include "surface.h" #include +#include "skwasm_support.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h" @@ -34,12 +35,9 @@ Surface::Surface() { skwasm_syncTimeOriginForThread(_thread); } -// Main thread only +// Worker thread only void Surface::dispose() { - assert(emscripten_is_main_browser_thread()); - emscripten_dispatch_to_thread(_thread, EM_FUNC_SIG_VI, - reinterpret_cast(fDispose), nullptr, - this); + delete this; } // Main thread only @@ -65,9 +63,7 @@ uint32_t Surface::rasterizeImage(SkImage* image, ImageByteFormat format) { uint32_t callbackId = ++_currentCallbackId; image->ref(); - emscripten_dispatch_to_thread(_thread, EM_FUNC_SIG_VIIII, - reinterpret_cast(fRasterizeImage), - nullptr, this, image, format, callbackId); + skwasm_dispatchRasterizeImage(_thread, this, image, format, callbackId); return callbackId; } @@ -122,11 +118,6 @@ void Surface::_init() { emscripten_glGetIntegerv(GL_STENCIL_BITS, &_stencil); } -// Worker thread only -void Surface::_dispose() { - delete this; -} - // Worker thread only void Surface::_resizeCanvasToFit(int width, int height) { if (!_surface || width > _canvasWidth || height > _canvasHeight) { @@ -175,9 +166,10 @@ void Surface::renderPicturesOnWorker(sk_sp* pictures, skwasm_resolveAndPostImages(this, imagePromiseArray, rasterStart, callbackId); } -void Surface::_rasterizeImage(SkImage* image, - ImageByteFormat format, - uint32_t callbackId) { +// Worker thread only +void Surface::rasterizeImageOnWorker(SkImage* image, + ImageByteFormat format, + uint32_t callbackId) { // We handle PNG encoding with browser APIs so that we can omit libpng from // skia to save binary size. assert(format != ImageByteFormat::png); @@ -192,17 +184,35 @@ void Surface::_rasterizeImage(SkImage* image, size_t byteSize = info.computeByteSize(bytesPerRow); data = SkData::MakeUninitialized(byteSize); uint8_t* pixels = reinterpret_cast(data->writable_data()); - bool success = image->readPixels(_grContext.get(), image->imageInfo(), pixels, - bytesPerRow, 0, 0); - if (!success) { - printf("Failed to read pixels from image!\n"); - data = nullptr; - } - emscripten_async_run_in_main_runtime_thread( - EM_FUNC_SIG_VIII, fOnRasterizeComplete, this, data.release(), callbackId); + + // TODO(jacksongardner): + // Normally we'd just call `readPixels` on the image. However, this doesn't + // actually work in some cases due to a skia bug. Instead, we just draw the + // image to our scratch canvas and grab the pixels out directly with + // `glReadPixels`. Once the skia bug is fixed, we should switch back to using + // `SkImage::readPixels` instead. + // See https://g-issues.skia.org/issues/349201915 + _resizeCanvasToFit(image->width(), image->height()); + auto canvas = _surface->getCanvas(); + canvas->drawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc); + + // We want the pixels from the upper left corner, but glReadPixels gives us + // the pixels from the lower left corner. So we have to flip the image when we + // are drawing it to get the pixels in the desired order. + canvas->save(); + canvas->scale(1, -1); + canvas->drawImage(image, 0, -_canvasHeight); + canvas->restore(); + _grContext->flush(_surface.get()); + + emscripten_glReadPixels(0, 0, image->width(), image->height(), GL_RGBA, + GL_UNSIGNED_BYTE, reinterpret_cast(pixels)); + + image->unref(); + skwasm_postRasterizeResult(this, data.release(), callbackId); } -void Surface::_onRasterizeComplete(SkData* data, uint32_t callbackId) { +void Surface::onRasterizeComplete(uint32_t callbackId, SkData* data) { _callbackHandler(callbackId, data, __builtin_wasm_ref_null_extern()); } @@ -212,22 +222,18 @@ void Surface::onRenderComplete(uint32_t callbackId, SkwasmObject imageBitmap) { _callbackHandler(callbackId, nullptr, imageBitmap); } -void Surface::fDispose(Surface* surface) { - surface->_dispose(); +TextureSourceWrapper::TextureSourceWrapper(unsigned long threadId, + SkwasmObject textureSource) + : _rasterThreadId(threadId) { + skwasm_setAssociatedObjectOnThread(_rasterThreadId, this, textureSource); } -void Surface::fOnRasterizeComplete(Surface* surface, - SkData* imageData, - uint32_t callbackId) { - surface->_onRasterizeComplete(imageData, callbackId); +TextureSourceWrapper::~TextureSourceWrapper() { + skwasm_disposeAssociatedObjectOnThread(_rasterThreadId, this); } -void Surface::fRasterizeImage(Surface* surface, - SkImage* image, - ImageByteFormat format, - uint32_t callbackId) { - surface->_rasterizeImage(image, format, callbackId); - image->unref(); +SkwasmObject TextureSourceWrapper::getTextureSource() { + return skwasm_getAssociatedObject(this); } SKWASM_EXPORT Surface* surface_create() { @@ -245,6 +251,12 @@ SKWASM_EXPORT void surface_setCallbackHandler( } SKWASM_EXPORT void surface_destroy(Surface* surface) { + // Dispatch to the worker + skwasm_dispatchDisposeSurface(surface->getThreadId(), surface); +} + +SKWASM_EXPORT void surface_dispose(Surface* surface) { + // This should be called directly only on the worker surface->dispose(); } @@ -272,10 +284,23 @@ SKWASM_EXPORT uint32_t surface_rasterizeImage(Surface* surface, return surface->rasterizeImage(image, format); } +SKWASM_EXPORT void surface_rasterizeImageOnWorker(Surface* surface, + SkImage* image, + ImageByteFormat format, + uint32_t callbackId) { + surface->rasterizeImageOnWorker(image, format, callbackId); +} + // This is used by the skwasm JS support code to call back into C++ when the // we finish creating the image bitmap, which is an asynchronous operation. SKWASM_EXPORT void surface_onRenderComplete(Surface* surface, uint32_t callbackId, SkwasmObject imageBitmap) { - return surface->onRenderComplete(callbackId, imageBitmap); + surface->onRenderComplete(callbackId, imageBitmap); +} + +SKWASM_EXPORT void surface_onRasterizeComplete(Surface* surface, + SkData* data, + uint32_t callbackId) { + surface->onRasterizeComplete(callbackId, data); } diff --git a/lib/web_ui/skwasm/surface.h b/lib/web_ui/skwasm/surface.h index 7e1d5fbb526e1..4756b8c5618d7 100644 --- a/lib/web_ui/skwasm/surface.h +++ b/lib/web_ui/skwasm/surface.h @@ -13,7 +13,6 @@ #include #include #include "export.h" -#include "skwasm_support.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkPicture.h" @@ -36,16 +35,10 @@ enum class ImageByteFormat { class TextureSourceWrapper { public: - TextureSourceWrapper(unsigned long threadId, SkwasmObject textureSource) - : _rasterThreadId(threadId) { - skwasm_setAssociatedObjectOnThread(_rasterThreadId, this, textureSource); - } + TextureSourceWrapper(unsigned long threadId, SkwasmObject textureSource); + ~TextureSourceWrapper(); - ~TextureSourceWrapper() { - skwasm_disposeAssociatedObjectOnThread(_rasterThreadId, this); - } - - SkwasmObject getTextureSource() { return skwasm_getAssociatedObject(this); } + SkwasmObject getTextureSource(); private: unsigned long _rasterThreadId; @@ -66,6 +59,7 @@ class Surface { uint32_t rasterizeImage(SkImage* image, ImageByteFormat format); void setCallbackHandler(CallbackHandler* callbackHandler); void onRenderComplete(uint32_t callbackId, SkwasmObject imageBitmap); + void onRasterizeComplete(uint32_t callbackId, SkData* data); // Any thread std::unique_ptr createTextureSourceWrapper( @@ -76,17 +70,15 @@ class Surface { int pictureCount, uint32_t callbackId, double rasterStart); + void rasterizeImageOnWorker(SkImage* image, + ImageByteFormat format, + uint32_t callbackId); private: void _runWorker(); void _init(); - void _dispose(); void _resizeCanvasToFit(int width, int height); void _recreateSurface(); - void _rasterizeImage(SkImage* image, - ImageByteFormat format, - uint32_t callbackId); - void _onRasterizeComplete(SkData* data, uint32_t callbackId); std::string _canvasID; CallbackHandler* _callbackHandler = nullptr; @@ -103,18 +95,6 @@ class Surface { GrGLint _stencil; pthread_t _thread; - - static void fDispose(Surface* surface); - static void fOnRenderComplete(Surface* surface, - uint32_t callbackId, - SkwasmObject imageBitmap); - static void fRasterizeImage(Surface* surface, - SkImage* image, - ImageByteFormat format, - uint32_t callbackId); - static void fOnRasterizeComplete(Surface* surface, - SkData* imageData, - uint32_t callbackId); }; } // namespace Skwasm diff --git a/lib/web_ui/skwasm/wrappers.h b/lib/web_ui/skwasm/wrappers.h index 8fdee6584ea62..b27e29f2d2c05 100644 --- a/lib/web_ui/skwasm/wrappers.h +++ b/lib/web_ui/skwasm/wrappers.h @@ -13,6 +13,8 @@ namespace Skwasm { +using SkwasmObject = __externref_t; + struct SurfaceWrapper { EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context; sk_sp grContext; diff --git a/lib/web_ui/test/ui/image_golden_test.dart b/lib/web_ui/test/ui/image_golden_test.dart index 198a74e893ab9..2b1f31277b699 100644 --- a/lib/web_ui/test/ui/image_golden_test.dart +++ b/lib/web_ui/test/ui/image_golden_test.dart @@ -280,6 +280,9 @@ Future testMain() async { final ByteData? rgbaData = await image.toByteData(); expect(rgbaData, isNotNull); expect(rgbaData!.lengthInBytes, isNonZero); + + // Make sure it isn't all zeros. + expect(rgbaData.buffer.asUint8List().any((int byte) => byte != 0), true); }); test('toByteData_png', () async { From 22e0c591557f48898f0afb23658df0924a5ef745 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 15:52:02 -0400 Subject: [PATCH 24/88] Roll Skia from da1ea4eb0270 to 04133a5bf21f (2 revisions) (#53566) https://skia.googlesource.com/skia.git/+log/da1ea4eb0270..04133a5bf21f 2024-06-25 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll ANGLE from 3c472b45024a to 016ef60d5f12 (12 revisions) 2024-06-25 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll Dawn from b6d4a58d3894 to b1c855cdc6b7 (3 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index a4db67c7b5e1f..343a801393207 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'da1ea4eb0270a9451778ea57cc6b535ae99505de', + 'skia_revision': '04133a5bf21fddc5641e4b5429175931dfce5953', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From f271fd0726a95f3fa48d4a39fc68334688b784aa Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 17:54:14 -0400 Subject: [PATCH 25/88] Roll Skia from 04133a5bf21f to ea8ec1a618b0 (3 revisions) (#53569) https://skia.googlesource.com/skia.git/+log/04133a5bf21f..ea8ec1a618b0 2024-06-25 gavinmak@google.com Support _RegenerateAllExamplesCPP on cog 2024-06-25 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll vulkan-deps from 9365edbe34f5 to 465cc29f79bc (6 revisions) 2024-06-25 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll Dawn from b1c855cdc6b7 to dc1551316ebe (8 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 343a801393207..bd6b7e83c5d49 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '04133a5bf21fddc5641e4b5429175931dfce5953', + 'skia_revision': 'ea8ec1a618b079fab4aa7c29a1fba6b168a49100', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 6c367e7533c521214e70a26c1db4a61c285e06e6 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 18:04:01 -0400 Subject: [PATCH 26/88] Roll Dart SDK from 65ab2f2cf0d3 to 38bb74f63829 (1 revision) (#53570) https://dart.googlesource.com/sdk.git/+log/65ab2f2cf0d3..38bb74f63829 2024-06-25 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-299.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_dart | 6 ++---- sky/packages/sky_engine/LICENSE | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/DEPS b/DEPS index bd6b7e83c5d49..dbedc9653cdc6 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '65ab2f2cf0d32dfb966bc1713bac46a2fad3d7f7', + 'dart_revision': '38bb74f63829eb08a2bd191226c40064aa457ee0', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index 642aade7635f6..a6a42bae49d9a 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: 0e4af40f333ea146834d901da41a1124 +Signature: 5f25db7a3b96987251f429d03beef50e ==================================================================================================== LIBRARY: dart @@ -3914,7 +3914,6 @@ ORIGIN: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibilit ORIGIN: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/int_patch.dart + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/string_buffer_patch.dart + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/string_patch.dart + ../../../flutter/third_party/dart/LICENSE -ORIGIN: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/typed_data.dart + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/typed_data_patch.dart + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/sdk/lib/async/future_extensions.dart + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/sdk/lib/js_interop/js_interop.dart + ../../../flutter/third_party/dart/LICENSE @@ -3978,7 +3977,6 @@ FILE: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/ FILE: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/int_patch.dart FILE: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/string_buffer_patch.dart FILE: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/string_patch.dart -FILE: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/typed_data.dart FILE: ../../../flutter/third_party/dart/sdk/lib/_internal/wasm_js_compatibility/lib/typed_data_patch.dart FILE: ../../../flutter/third_party/dart/sdk/lib/async/future_extensions.dart FILE: ../../../flutter/third_party/dart/sdk/lib/js_interop/js_interop.dart @@ -4753,7 +4751,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/bb18127b2a8e1a1afd882efcc38271212b238ff3 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/38bb74f63829eb08a2bd191226c40064aa457ee0 /third_party/fallback_root_certificates/ ==================================================================================================== diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index 6796ba30943be..d24da023f22be 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/65ab2f2cf0d32dfb966bc1713bac46a2fad3d7f7 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/38bb74f63829eb08a2bd191226c40064aa457ee0 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From 25af762ffbb320ebab6aea25ff8606300aa870fc Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 25 Jun 2024 19:22:13 -0400 Subject: [PATCH 27/88] Roll Skia from ea8ec1a618b0 to 7cbcb2f0e818 (4 revisions) (#53573) https://skia.googlesource.com/skia.git/+log/ea8ec1a618b0..7cbcb2f0e818 2024-06-25 bungeman@google.com Update CMake generator compile flags 2024-06-25 robertphillips@google.com [graphite] Make PrecompileMaskFilter part of the public Precompile API 2024-06-25 brianosman@google.com Remove SK_LEGACY_RECT_DASHING_BUG 2024-06-25 jvanverth@google.com Change wacky_yuv GMs to split full colorspaces from limited. If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index dbedc9653cdc6..965b49f1a7dae 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'ea8ec1a618b079fab4aa7c29a1fba6b168a49100', + 'skia_revision': '7cbcb2f0e818c269e95210303bf67bef35c9b2f6', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 6bf7f61dd3490..bd8c215ebf97d 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 4c1d441ade8acae524a700a4904ba032 +Signature: aaa8de3db2f948b015a6f44c7227d703 ==================================================================================================== LIBRARY: etc1 @@ -9516,6 +9516,7 @@ ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/Precom ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileBase.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileBlender.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileColorFilter.h + ../../../flutter/third_party/skia/LICENSE +ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileMaskFilter.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileShader.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/modules/skshaper/include/SkShaper_coretext.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/modules/skshaper/include/SkShaper_factory.h + ../../../flutter/third_party/skia/LICENSE @@ -9563,6 +9564,7 @@ ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/Precompile ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileBlenderPriv.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileColorFilter.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileColorFiltersPriv.h + ../../../flutter/third_party/skia/LICENSE +ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileMaskFilter.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShader.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShaderPriv.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShadersPriv.h + ../../../flutter/third_party/skia/LICENSE @@ -9603,6 +9605,7 @@ FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/Precompi FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileBase.h FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileBlender.h FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileColorFilter.h +FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileMaskFilter.h FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileShader.h FILE: ../../../flutter/third_party/skia/modules/skshaper/include/SkShaper_coretext.h FILE: ../../../flutter/third_party/skia/modules/skshaper/include/SkShaper_factory.h @@ -9650,6 +9653,7 @@ FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileBl FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileBlenderPriv.h FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileColorFilter.cpp FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileColorFiltersPriv.h +FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileMaskFilter.cpp FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShader.cpp FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShaderPriv.h FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShadersPriv.h From 6882e0bbabf74f05d7393e5c4fa38c6a8eb91aef Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 25 Jun 2024 16:54:26 -0700 Subject: [PATCH 28/88] Remove FlutterUndoManagerPlugin handlers from undo manager on dealloc (#53553) When `FlutterUndoManagerPlugin` deallocated, it is supposed to deregister itself from the `NSUndoManager` stack. However, during dealloc `_undoManagerDelegate.undoManager` is nil (`_undoManagerDelegate` = the engine, and `undoManager` was its view controller's `undoManager`, which was already gone). Since `_undoManagerDelegate.undoManager` is nil, it doesn't actually call `-[NSUndoManager removeAllActionsWithTarget]`. In the add-to-app scenario, after the view controller pops back to the native view, and "undo" is invoked, the undo action for the `FlutterUndoManagerPlugin` is handled, but it already dealloced so crash. Fixes https://github.com/flutter/flutter/issues/150408 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- .../Source/FlutterUndoManagerPlugin.mm | 15 +++++--- .../Source/FlutterUndoManagerPluginTest.mm | 35 +++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPlugin.mm index 6eeb106c16ec3..32810dcacc9c1 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPlugin.mm @@ -13,6 +13,10 @@ @interface FlutterUndoManagerPlugin () @property(nonatomic, weak, readonly) id undoManagerDelegate; + +// When the delegate is `FlutterEngine` this will be the `FlutterViewController`'s undo manager. +// Strongly retain to ensure this target's actions are completely removed during dealloc. +@property(nonatomic) NSUndoManager* undoManager; @end @implementation FlutterUndoManagerPlugin @@ -28,13 +32,14 @@ - (instancetype)initWithDelegate:(id)undoManagerDele } - (void)dealloc { - [_undoManagerDelegate.undoManager removeAllActionsWithTarget:self]; + [_undoManager removeAllActionsWithTarget:self]; } - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { NSString* method = call.method; id args = call.arguments; if ([method isEqualToString:kSetUndoStateMethod]) { + self.undoManager = self.undoManagerDelegate.undoManager; [self setUndoState:args]; result(nil); } else { @@ -43,11 +48,11 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { } - (void)resetUndoManager { - [self.undoManagerDelegate.undoManager removeAllActionsWithTarget:self]; + [self.undoManager removeAllActionsWithTarget:self]; } - (void)registerUndoWithDirection:(FlutterUndoRedoDirection)direction { - NSUndoManager* undoManager = self.undoManagerDelegate.undoManager; + NSUndoManager* undoManager = self.undoManager; [undoManager beginUndoGrouping]; [undoManager registerUndoWithTarget:self handler:^(FlutterUndoManagerPlugin* target) { @@ -64,7 +69,7 @@ - (void)registerUndoWithDirection:(FlutterUndoRedoDirection)direction { } - (void)registerRedo { - NSUndoManager* undoManager = self.undoManagerDelegate.undoManager; + NSUndoManager* undoManager = self.undoManager; [undoManager beginUndoGrouping]; [undoManager registerUndoWithTarget:self handler:^(id target) { @@ -76,7 +81,7 @@ - (void)registerRedo { } - (void)setUndoState:(NSDictionary*)dictionary { - NSUndoManager* undoManager = self.undoManagerDelegate.undoManager; + NSUndoManager* undoManager = self.undoManager; BOOL groupsByEvent = undoManager.groupsByEvent; undoManager.groupsByEvent = NO; BOOL canUndo = [dictionary[kCanUndo] boolValue]; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPluginTest.mm index 62dcb8089a237..d5d445ca62cee 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPluginTest.mm @@ -27,6 +27,7 @@ @interface FakeFlutterUndoManagerDelegate : NSObject Date: Tue, 25 Jun 2024 22:43:34 -0400 Subject: [PATCH 29/88] Roll Fuchsia Linux SDK from WUN7NQK04NjF9fRmf... to n2dgSmMCaCO7ujvmr... (#53575) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/fuchsia-linux-sdk-flutter-engine Please CC jimgraham@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_fuchsia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 965b49f1a7dae..3b0b6fa39f2c7 100644 --- a/DEPS +++ b/DEPS @@ -979,7 +979,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/sdk/core/linux-amd64', - 'version': 'WUN7NQK04NjF9fRmfM16ILdIhytQAHB7O1631G4HsIEC' + 'version': 'n2dgSmMCaCO7ujvmrHIPlsgMLgz3zcicHJUi7-7_zgkC' } ], 'condition': 'download_fuchsia_deps and not download_fuchsia_sdk', diff --git a/ci/licenses_golden/licenses_fuchsia b/ci/licenses_golden/licenses_fuchsia index 0d26e314e01e6..5829845345963 100644 --- a/ci/licenses_golden/licenses_fuchsia +++ b/ci/licenses_golden/licenses_fuchsia @@ -1,4 +1,4 @@ -Signature: a5329b90f250b2818eb738443619fbc2 +Signature: a4b111728b0d148c1fac1b95d99eb2ff ==================================================================================================== LIBRARY: fuchsia_sdk From ea811585e9bb969ddcde0817009ab564abbf3842 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 01:38:57 -0400 Subject: [PATCH 30/88] Roll Skia from 7cbcb2f0e818 to 0c9a66786ba1 (1 revision) (#53576) https://skia.googlesource.com/skia.git/+log/7cbcb2f0e818..0c9a66786ba1 2024-06-26 skia-autoroll@skia-public.iam.gserviceaccount.com Roll vulkan-deps from 465cc29f79bc to 1c484942880c (3 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 3b0b6fa39f2c7..e95338098aba7 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '7cbcb2f0e818c269e95210303bf67bef35c9b2f6', + 'skia_revision': '0c9a66786ba1062a4af966cf25a6f3eaeb628645', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 53057b35af99ee4a447f578ba9f0167c0c8b0e4a Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 03:01:23 -0400 Subject: [PATCH 31/88] Roll Skia from 0c9a66786ba1 to 7e85023a57b7 (3 revisions) (#53577) https://skia.googlesource.com/skia.git/+log/0c9a66786ba1..7e85023a57b7 2024-06-26 skia-autoroll@skia-public.iam.gserviceaccount.com Roll SwiftShader from de870ac7518f to a0ec371d8331 (2 revisions) 2024-06-26 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Dawn from dc1551316ebe to 720ace3b91cf (13 revisions) 2024-06-26 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Skia Infra from d6925c2a17cc to 72fd79ddaace (8 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index e95338098aba7..59411df2623a1 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '0c9a66786ba1062a4af966cf25a6f3eaeb628645', + 'skia_revision': '7e85023a57b736bc9f6393c46c3d344a48abec17', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index bd8c215ebf97d..6ad688de4005a 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: aaa8de3db2f948b015a6f44c7227d703 +Signature: 3691c286df8ed5dc5ed6ed50b4b1125f ==================================================================================================== LIBRARY: etc1 From d4624a36712bce5a48ec8424eff5130654b2b36a Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 05:51:23 -0400 Subject: [PATCH 32/88] Roll Skia from 7e85023a57b7 to 79587650d153 (1 revision) (#53578) https://skia.googlesource.com/skia.git/+log/7e85023a57b7..79587650d153 2024-06-26 skia-autoroll@skia-public.iam.gserviceaccount.com Roll ANGLE from 016ef60d5f12 to 046327343595 (6 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 59411df2623a1..fc99b0677d510 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '7e85023a57b736bc9f6393c46c3d344a48abec17', + 'skia_revision': '79587650d153f7901d5c346b58f336c136427854', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From d4ef035dcab7730c75f9d59ba1fcdb335127695c Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 10:55:23 -0400 Subject: [PATCH 33/88] Roll Skia from 79587650d153 to 354b30fe7ab5 (2 revisions) (#53580) https://skia.googlesource.com/skia.git/+log/79587650d153..354b30fe7ab5 2024-06-26 zhusida@bytedance.com Reland "Add 16bit BT2020, YCGCO color space support" 2024-06-26 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll Dawn from 720ace3b91cf to fa24f1553bec (16 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index fc99b0677d510..55f75ea2ca115 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '79587650d153f7901d5c346b58f336c136427854', + 'skia_revision': '354b30fe7ab54c325bf07e92126b57dcd608a131', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 6ad688de4005a..7112a3ab53abe 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 3691c286df8ed5dc5ed6ed50b4b1125f +Signature: a02b75f777c977c06fe7fa3ba9368969 ==================================================================================================== LIBRARY: etc1 From 59aae20678d72300e9c9ffc0728eb630e721ef42 Mon Sep 17 00:00:00 2001 From: Srujan Gaddam <58529443+srujzs@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:32:08 -0700 Subject: [PATCH 34/88] Ignore lints that will be triggered by ExternalDartReference changes (#53572) https://dart-review.googlesource.com/c/sdk/+/370663 makes ExternalDartReference generic. By doing so, it triggers two cast_nullable_to_non_nullable lints that need to be silenced for it to land. Once the above SDK changes land, this can be refactored to utilize the generic and avoid the manual cast altogether. --- lib/web_ui/lib/src/engine/canvaskit/native_memory.dart | 1 + lib/web_ui/lib/src/engine/skwasm/skwasm_impl/memory.dart | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/web_ui/lib/src/engine/canvaskit/native_memory.dart b/lib/web_ui/lib/src/engine/canvaskit/native_memory.dart index 8af6b3aaa5532..4caf251c031cc 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/native_memory.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/native_memory.dart @@ -22,6 +22,7 @@ import 'package:ui/src/engine.dart'; /// 6. We call `delete` on SkPaint. DomFinalizationRegistry _finalizationRegistry = DomFinalizationRegistry( (ExternalDartReference boxedUniq) { + // ignore: cast_nullable_to_non_nullable final UniqueRef uniq = boxedUniq.toDartObject as UniqueRef; uniq.collect(); }.toJS diff --git a/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/memory.dart b/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/memory.dart index ef60ac0ae7c82..d6d739c7376ac 100644 --- a/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/memory.dart +++ b/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/memory.dart @@ -29,6 +29,7 @@ typedef DisposeFunction = void Function(Pointer); class SkwasmFinalizationRegistry { SkwasmFinalizationRegistry(this.dispose) : registry = DomFinalizationRegistry(((ExternalDartReference address) => + // ignore: cast_nullable_to_non_nullable dispose(Pointer.fromAddress(address.toDartObject as int)) ).toJS); From 32bbc62379719dda51f00e28e4eac18a05922c16 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 12:48:23 -0400 Subject: [PATCH 35/88] Roll Skia from 354b30fe7ab5 to e836fa986829 (3 revisions) (#53583) https://skia.googlesource.com/skia.git/+log/354b30fe7ab5..e836fa986829 2024-06-26 nathanasanchez@google.com [Graphite] Remove hard-coded buffer indices 2024-06-26 michaelludwig@google.com [graphite] Consolidate built-in shader-snippet tables 2024-06-26 skia-autoroll@skia-public.iam.gserviceaccount.com Roll SK Tool from 72fd79ddaace to 79660091faba If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 55f75ea2ca115..6ef133c570da8 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '354b30fe7ab54c325bf07e92126b57dcd608a131', + 'skia_revision': 'e836fa986829bb8fb98de54dd442f3c25c2ce48c', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 7112a3ab53abe..f778b78ead015 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: a02b75f777c977c06fe7fa3ba9368969 +Signature: 5fa5bc6e6294c2e106c9d450f97d2d7e ==================================================================================================== LIBRARY: etc1 From c0017bed42c24071f3f441b214b9f3698751e903 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Wed, 26 Jun 2024 09:54:20 -0700 Subject: [PATCH 36/88] Roll the archive package to version 3.6.1 (#53582) This version does not use the deprecated UnmodifiableInt32ListView API. --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 6ef133c570da8..077266f071e3c 100644 --- a/DEPS +++ b/DEPS @@ -682,7 +682,7 @@ deps = { # Dart packages 'src/flutter/third_party/pkg/archive': - Var('chromium_git') + '/external/github.com/brendan-duncan/archive.git' + '@' + '9de7a0544457c6aba755ccb65abb41b0dc1db70d', # 3.1.2 + Var('chromium_git') + '/external/github.com/brendan-duncan/archive.git' + '@' + 'f1d164f8f5d8aea0be620a9b1e8d300b75a29388', # 3.6.1 'src/flutter/third_party/pkg/coverage': Var('flutter_git') + '/third_party/coverage.git' + '@' + 'bb0ab721ee4ceef1abfa413d8d6fd46013b583b9', # 1.7.2 From e03cf86c4170f9c010c5189aa6299609c41b88d3 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 14:08:08 -0400 Subject: [PATCH 37/88] Roll Skia from e836fa986829 to 695d35a0559e (1 revision) (#53584) https://skia.googlesource.com/skia.git/+log/e836fa986829..695d35a0559e 2024-06-26 michaelludwig@google.com [graphite] Use sk_FragCoord for dithering If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 077266f071e3c..a83afa9e1f582 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'e836fa986829bb8fb98de54dd442f3c25c2ce48c', + 'skia_revision': '695d35a0559e46d96eff758d094752e1076060ca', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index f778b78ead015..47259c3e1d419 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 5fa5bc6e6294c2e106c9d450f97d2d7e +Signature: 2bb9ca2c4a4df2de8e1c6d6d9a822a65 ==================================================================================================== LIBRARY: etc1 From 61586debc1bc246bcc970854b6b1765f9f838038 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Wed, 26 Jun 2024 11:59:18 -0700 Subject: [PATCH 38/88] Move impeller-cmake-example to flutter/third_party. (#53589) ... as part of buildmoot. I _think_ this is all that is needed but am not confident. --- DEPS | 4 ++-- tools/gn | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DEPS b/DEPS index a83afa9e1f582..0647f499ace74 100644 --- a/DEPS +++ b/DEPS @@ -1008,7 +1008,7 @@ deps = { 'dep_type': 'cipd', }, - 'src/third_party/impeller-cmake-example': { + 'src/flutter/third_party/impeller-cmake-example': { 'url': Var('flutter_git') + '/third_party/impeller-cmake-example.git' + '@' + '9f8298ec31dcbebbf019bd487888166abf2f55e6', 'condition': 'download_impeller_cmake_example', }, @@ -1136,7 +1136,7 @@ hooks = [ 'python3', 'src/flutter/ci/impeller_cmake_build_test.py', '--path', - 'third_party/impeller-cmake-example', + 'flutter/third_party/impeller-cmake-example', '--setup', ] }, diff --git a/tools/gn b/tools/gn index e90065d524864..ac3cd935881a0 100755 --- a/tools/gn +++ b/tools/gn @@ -824,7 +824,7 @@ def to_gn_wasm_args(args, gn_args): def run_impeller_cmake(args): - impeller_cmake_dir = os.path.join('third_party', 'impeller-cmake-example') + impeller_cmake_dir = os.path.join('flutter', 'third_party', 'impeller-cmake-example') if not os.path.isdir(os.path.join(SRC_ROOT, impeller_cmake_dir)): print('The Impeller cmake example directory "{}" does not exist'.format(impeller_cmake_dir)) return 1 From 62cce3b08f2d3e6e1dd4cdef2b2b799fd2dc8584 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 15:20:20 -0400 Subject: [PATCH 39/88] Roll Skia from 695d35a0559e to 0a979d9f3606 (3 revisions) (#53591) https://skia.googlesource.com/skia.git/+log/695d35a0559e..0a979d9f3606 2024-06-26 lehoangquyen@google.com GraphiteDawn: Use larger static storage for bindgroup keys. 2024-06-26 skia-autoroll@skia-public.iam.gserviceaccount.com Roll vulkan-deps from 1c484942880c to 782b625ca1dc (3 revisions) 2024-06-26 bungeman@google.com Roll ninja If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 0647f499ace74..2de9e11232e0d 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '695d35a0559e46d96eff758d094752e1076060ca', + 'skia_revision': '0a979d9f360659e034fee2395c9e12fa08dc7f5b', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 47259c3e1d419..7c52a0f72c56e 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 2bb9ca2c4a4df2de8e1c6d6d9a822a65 +Signature: 27b98f44888fefbb6ad6d9aaf41c952f ==================================================================================================== LIBRARY: etc1 From 1d5e3cc55a75205eeb5e3567b494da8956dd92d6 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Wed, 26 Jun 2024 12:31:02 -0700 Subject: [PATCH 40/88] Replace `Log.w` with `Log.d`, and tidy the file up a bit. (#53586) Closes https://github.com/flutter/flutter/issues/150849. (Almost all of these are mechanical auto-fix changes from Android Studio/Best Practices). --- .../engine/renderer/FlutterRenderer.java | 105 ++++++++---------- 1 file changed, 44 insertions(+), 61 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index 13b57c7d98e75..445e331845c13 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -334,7 +334,7 @@ final class SurfaceTextureRegistryEntry textureWrapper.markDirty(); scheduleEngineFrame(); }; - // The callback relies on being executed on the UI thread (unsynchronised read of + // The callback relies on being executed on the UI thread (un-synchronised read of // mNativeView and also the engine code check for platform thread in // Shell::OnPlatformViewMarkTextureFrameAvailable), so we explicitly pass a Handler for the // current thread. @@ -449,7 +449,7 @@ final class ImageReaderSurfaceProducer // Will be true in tests and on Android API < 33. private boolean ignoringFence = false; - private boolean trimOnMemoryPressure = CLEANUP_ON_MEMORY_PRESSURE; + private static final boolean trimOnMemoryPressure = CLEANUP_ON_MEMORY_PRESSURE; // The requested width and height are updated by setSize. private int requestedWidth = 1; @@ -466,11 +466,10 @@ final class ImageReaderSurfaceProducer private long lastScheduleTime = 0; private int numTrims = 0; - private Object lock = new Object(); + private final Object lock = new Object(); // REQUIRED: The following fields must only be accessed when lock is held. - private final ArrayDeque imageReaderQueue = new ArrayDeque(); - private final HashMap perImageReaders = - new HashMap(); + private final ArrayDeque imageReaderQueue = new ArrayDeque<>(); + private final HashMap perImageReaders = new HashMap<>(); private PerImage lastDequeuedImage = null; private PerImageReader lastReaderDequeuedFrom = null; private Callback callback = null; @@ -489,29 +488,28 @@ public PerImage(Image image, long queuedTime) { /** Internal class: state held per ImageReader. */ private class PerImageReader { public final ImageReader reader; - private final ArrayDeque imageQueue = new ArrayDeque(); + private final ArrayDeque imageQueue = new ArrayDeque<>(); private boolean closed = false; - private final ImageReader.OnImageAvailableListener onImageAvailableListener = - reader -> { - Image image = null; - try { - image = reader.acquireLatestImage(); - } catch (IllegalStateException e) { - Log.e(TAG, "onImageAvailable acquireLatestImage failed: " + e); - } - if (image == null) { - return; - } - if (released || closed) { - image.close(); - return; - } - onImage(reader, image); - }; - public PerImageReader(ImageReader reader) { this.reader = reader; + ImageReader.OnImageAvailableListener onImageAvailableListener = + r -> { + Image image = null; + try { + image = r.acquireLatestImage(); + } catch (IllegalStateException e) { + Log.e(TAG, "onImageAvailable acquireLatestImage failed: " + e); + } + if (image == null) { + return; + } + if (released || closed) { + image.close(); + return; + } + onImage(r, image); + }; reader.setOnImageAvailableListener( onImageAvailableListener, new Handler(Looper.getMainLooper())); } @@ -526,7 +524,7 @@ PerImage queueImage(Image image) { while (imageQueue.size() > 2) { PerImage r = imageQueue.removeFirst(); if (VERBOSE_LOGS) { - Log.i(TAG, "" + reader.hashCode() + " force closed image=" + r.image.hashCode()); + Log.i(TAG, reader.hashCode() + " force closed image=" + r.image.hashCode()); } r.image.close(); } @@ -534,16 +532,15 @@ PerImage queueImage(Image image) { } PerImage dequeueImage() { - if (imageQueue.size() == 0) { + if (imageQueue.isEmpty()) { return null; } - PerImage r = imageQueue.removeFirst(); - return r; + return imageQueue.removeFirst(); } /** returns true if we can prune this reader */ boolean canPrune() { - return imageQueue.size() == 0 && lastReaderDequeuedFrom != this; + return imageQueue.isEmpty() && lastReaderDequeuedFrom != this; } void close() { @@ -557,8 +554,7 @@ void close() { } double deltaMillis(long deltaNanos) { - double ms = (double) deltaNanos / (double) 1000000.0; - return ms; + return (double) deltaNanos / 1000000.0; } PerImageReader getOrCreatePerImageReader(ImageReader reader) { @@ -579,7 +575,7 @@ void pruneImageReaderQueue() { // Prune nodes from the head of the ImageReader queue. while (imageReaderQueue.size() > 1) { PerImageReader r = imageReaderQueue.peekFirst(); - if (!r.canPrune()) { + if (r == null || !r.canPrune()) { // No more ImageReaders can be pruned this round. break; } @@ -594,7 +590,7 @@ void pruneImageReaderQueue() { } void onImage(ImageReader reader, Image image) { - PerImage queuedImage = null; + PerImage queuedImage; synchronized (lock) { PerImageReader perReader = getOrCreatePerImageReader(reader); queuedImage = perReader.queueImage(image); @@ -609,8 +605,7 @@ void onImage(ImageReader reader, Image image) { long queueDelta = now - lastQueueTime; Log.i( TAG, - "" - + reader.hashCode() + reader.hashCode() + " enqueued image=" + queuedImage.image.hashCode() + " queueDelta=" @@ -640,8 +635,7 @@ PerImage dequeueImage() { long scheduleDelay = now - lastScheduleTime; Log.i( TAG, - "" - + reader.reader.hashCode() + reader.reader.hashCode() + " dequeued image=" + r.image.hashCode() + " queuedFor= " @@ -659,8 +653,7 @@ PerImage dequeueImage() { if (VERBOSE_LOGS) { Log.i( TAG, - "" - + lastReaderDequeuedFrom.reader.hashCode() + lastReaderDequeuedFrom.reader.hashCode() + " closing image=" + lastDequeuedImage.image.hashCode()); } @@ -668,7 +661,6 @@ PerImage dequeueImage() { // it. We have just dequeued a new image (r). Close the previously dequeued // image. lastDequeuedImage.image.close(); - lastDequeuedImage = null; } // Remember the last image and reader dequeued from. We do this because we must // keep both of these alive until we are done presenting the image. @@ -750,7 +742,7 @@ private void maybeWaitOnFence(Image image) { } // Log once per ImageTextureEntry. ignoringFence = true; - Log.w(TAG, "ImageTextureEntry can't wait on the fence on Android < 33"); + Log.d(TAG, "ImageTextureEntry can't wait on the fence on Android < 33"); } ImageReaderSurfaceProducer(long id) { @@ -805,7 +797,7 @@ public int getHeight() { public Surface getSurface() { PerImageReader pir = getActiveReader(); if (VERBOSE_LOGS) { - Log.i(TAG, "" + pir.reader.hashCode() + " returning surface to render a new frame."); + Log.i(TAG, pir.reader.hashCode() + " returning surface to render a new frame."); } return pir.reader.getSurface(); } @@ -842,8 +834,7 @@ private PerImageReader getActiveReader() { ImageReader reader = createImageReader(); if (VERBOSE_LOGS) { Log.i( - TAG, - "" + reader.hashCode() + " created w=" + requestedWidth + " h=" + requestedHeight); + TAG, reader.hashCode() + " created w=" + requestedWidth + " h=" + requestedHeight); } return getOrCreatePerImageReader(reader); } @@ -878,20 +869,17 @@ private ImageReader createImageReader33() { builder.setImageFormat(ImageFormat.PRIVATE); // Hint that consumed images will only be read by GPU. builder.setUsage(HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE); - final ImageReader reader = builder.build(); - return reader; + return builder.build(); } @TargetApi(API_LEVELS.API_29) private ImageReader createImageReader29() { - final ImageReader reader = - ImageReader.newInstance( - requestedWidth, - requestedHeight, - ImageFormat.PRIVATE, - MAX_IMAGES, - HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE); - return reader; + return ImageReader.newInstance( + requestedWidth, + requestedHeight, + ImageFormat.PRIVATE, + MAX_IMAGES, + HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE); } private ImageReader createImageReader() { @@ -1012,7 +1000,7 @@ private void maybeWaitOnFence(Image image) { } // Log once per ImageTextureEntry. ignoringFence = true; - Log.w(TAG, "ImageTextureEntry can't wait on the fence on Android < 33"); + Log.d(TAG, "ImageTextureEntry can't wait on the fence on Android < 33"); } @Override @@ -1244,11 +1232,6 @@ private void scheduleEngineFrame() { flutterJNI.scheduleFrame(); } - // TODO(mattcarroll): describe the native behavior that this invokes - private void markTextureFrameAvailable(long textureId) { - flutterJNI.markTextureFrameAvailable(textureId); - } - // TODO(mattcarroll): describe the native behavior that this invokes private void unregisterTexture(long textureId) { flutterJNI.unregisterTexture(textureId); From a9511fb4315eae8556298b5ad11d7e77dfb70562 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 16:02:19 -0400 Subject: [PATCH 41/88] Roll Dart SDK from 38bb74f63829 to c01f907d34d8 (5 revisions) (#53585) https://dart.googlesource.com/sdk.git/+log/38bb74f63829..c01f907d34d8 2024-06-26 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-304.0.dev 2024-06-26 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-303.0.dev 2024-06-26 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-302.0.dev 2024-06-26 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-301.0.dev 2024-06-25 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-300.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 10 +++++----- ci/licenses_golden/excluded_files | 2 +- ci/licenses_golden/licenses_dart | 12 ++++++------ sky/packages/sky_engine/LICENSE | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/DEPS b/DEPS index 2de9e11232e0d..7c78247a4e3c6 100644 --- a/DEPS +++ b/DEPS @@ -56,11 +56,11 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '38bb74f63829eb08a2bd191226c40064aa457ee0', + 'dart_revision': 'c01f907d34d88fd133cbb1636e76c3cd57505eba', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py - 'dart_binaryen_rev': 'd844d2e77b402d562ade8cf8fd96759b587bf09d', + 'dart_binaryen_rev': '654ee6e2504f11fb0e982a2cf276bafa750f694b', 'dart_boringssl_gen_rev': '9c7294fd58261a79794f5afaa26598cf1442ad20', 'dart_boringssl_rev': 'd24a38200fef19150eef00cad35b138936c08767', 'dart_browser_launcher_rev': '7348ceae6508e5350771979c2951a54313303416', @@ -74,7 +74,7 @@ vars = { 'dart_pub_rev': 'ddc1c2fd2e2a7cd94a0b92ea033961a25f4ad517', 'dart_tools_rev': 'e660a68dce659311fb47735ab00365e26fca2fe3', 'dart_watcher_rev': 'c00fc2a6cd869cdebbc52e00af3d912d25745729', - 'dart_web_rev': '2fe754fb396cb9b87010f0318cfbfc5408346c48', + 'dart_web_rev': '6b8a46561b82de9b20d77d9ac491844d303ca08f', 'dart_webdev_rev': 'c56611255f3f02642da10750448a8c90a9fa7b47', 'dart_webkit_inspection_protocol_rev': '5740cc91eaeb13a02007b77b128fccf4b056db6e', 'dart_yaml_edit_rev': '08a146ef8f2c7aba908d2017c9ec840b882c9e51', @@ -344,7 +344,7 @@ deps = { # WARNING: Unused Dart dependencies in the list below till "WARNING:" marker are removed automatically - see create_updated_flutter_deps.py. 'src/flutter/third_party/dart/third_party/binaryen/src': - Var('chromium_git') + '/external/github.com/WebAssembly/binaryen.git@d844d2e77b402d562ade8cf8fd96759b587bf09d', + Var('chromium_git') + '/external/github.com/WebAssembly/binaryen.git@654ee6e2504f11fb0e982a2cf276bafa750f694b', 'src/flutter/third_party/dart/third_party/devtools': {'dep_type': 'cipd', 'packages': [{'package': 'dart/third_party/flutter/devtools', 'version': 'git_revision:a53696352fe1508c18d908a85b68c113b11dbe58'}]}, @@ -518,7 +518,7 @@ deps = { Var('dart_git') + '/yaml_edit.git' + '@' + Var('dart_yaml_edit_rev'), 'src/flutter/third_party/dart/tools/sdks/dart-sdk': - {'dep_type': 'cipd', 'packages': [{'package': 'dart/dart-sdk/${{platform}}', 'version': 'version:3.4.0-247.0.dev'}]}, + {'dep_type': 'cipd', 'packages': [{'package': 'dart/dart-sdk/${{platform}}', 'version': 'version:3.5.0-278.0.dev'}]}, # WARNING: end of dart dependencies list that is cleaned up automatically - see create_updated_flutter_deps.py. diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 859cf03ca6fa3..bec99eef744ad 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -1393,6 +1393,7 @@ ../../../flutter/third_party/dart/runtime/bin/process_test.cc ../../../flutter/third_party/dart/runtime/bin/secure_socket_utils_test.cc ../../../flutter/third_party/dart/runtime/bin/snapshot_utils_test.cc +../../../flutter/third_party/dart/runtime/bin/uri_test.cc ../../../flutter/third_party/dart/runtime/codereview.settings ../../../flutter/third_party/dart/runtime/docs ../../../flutter/third_party/dart/runtime/observatory/.gitignore @@ -1403,7 +1404,6 @@ ../../../flutter/third_party/dart/runtime/observatory/tests ../../../flutter/third_party/dart/runtime/observatory/update_sources.py ../../../flutter/third_party/dart/runtime/observatory/web/third_party/README.md -../../../flutter/third_party/dart/runtime/platform/uri_test.cc ../../../flutter/third_party/dart/runtime/tests ../../../flutter/third_party/dart/runtime/tools/.gitignore ../../../flutter/third_party/dart/runtime/tools/android_finder.py diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index a6a42bae49d9a..1f505c82bbc57 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: 5f25db7a3b96987251f429d03beef50e +Signature: 960100a262e744ffa698f14b7fe97776 ==================================================================================================== LIBRARY: dart @@ -4077,9 +4077,9 @@ LIBRARY: dart ORIGIN: ../../../flutter/third_party/dart/runtime/bin/ifaddrs.cc + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/runtime/bin/ifaddrs.h + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/runtime/bin/native_assets_api_impl.cc + ../../../flutter/third_party/dart/LICENSE +ORIGIN: ../../../flutter/third_party/dart/runtime/bin/uri.cc + ../../../flutter/third_party/dart/LICENSE +ORIGIN: ../../../flutter/third_party/dart/runtime/bin/uri.h + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/runtime/include/bin/native_assets_api.h + ../../../flutter/third_party/dart/LICENSE -ORIGIN: ../../../flutter/third_party/dart/runtime/platform/uri.cc + ../../../flutter/third_party/dart/LICENSE -ORIGIN: ../../../flutter/third_party/dart/runtime/platform/uri.h + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/runtime/tools/dartfuzz/flag_fuzzer.dart + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/runtime/vm/compiler/backend/dart_calling_conventions.cc + ../../../flutter/third_party/dart/LICENSE ORIGIN: ../../../flutter/third_party/dart/runtime/vm/compiler/backend/dart_calling_conventions.h + ../../../flutter/third_party/dart/LICENSE @@ -4097,9 +4097,9 @@ TYPE: LicenseType.bsd FILE: ../../../flutter/third_party/dart/runtime/bin/ifaddrs.cc FILE: ../../../flutter/third_party/dart/runtime/bin/ifaddrs.h FILE: ../../../flutter/third_party/dart/runtime/bin/native_assets_api_impl.cc +FILE: ../../../flutter/third_party/dart/runtime/bin/uri.cc +FILE: ../../../flutter/third_party/dart/runtime/bin/uri.h FILE: ../../../flutter/third_party/dart/runtime/include/bin/native_assets_api.h -FILE: ../../../flutter/third_party/dart/runtime/platform/uri.cc -FILE: ../../../flutter/third_party/dart/runtime/platform/uri.h FILE: ../../../flutter/third_party/dart/runtime/tools/dartfuzz/flag_fuzzer.dart FILE: ../../../flutter/third_party/dart/runtime/vm/compiler/backend/dart_calling_conventions.cc FILE: ../../../flutter/third_party/dart/runtime/vm/compiler/backend/dart_calling_conventions.h @@ -4751,7 +4751,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/38bb74f63829eb08a2bd191226c40064aa457ee0 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/c01f907d34d88fd133cbb1636e76c3cd57505eba /third_party/fallback_root_certificates/ ==================================================================================================== diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index d24da023f22be..d7c34b5d83416 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/38bb74f63829eb08a2bd191226c40064aa457ee0 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/c01f907d34d88fd133cbb1636e76c3cd57505eba /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From 6ae68272a303b327ff85da4d174c15a57bc3b374 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Wed, 26 Jun 2024 13:35:07 -0700 Subject: [PATCH 42/88] Copy `flutter/flutter/docs/engine` to `flutter/engine/docs` as-is (no changes) (#53595) See https://github.com/flutter/flutter/issues/150869. --- docs/Crashes.md | 134 +++++++ docs/Custom-Flutter-Engine-Embedders.md | 23 ++ ...om-Flutter-Engine-Embedding-in-AOT-Mode.md | 132 +++++++ docs/Debugging-the-engine.md | 147 ++++++++ docs/Engine-disk-footprint.md | 33 ++ ...ne-specific-Service-Protocol-extensions.md | 203 ++++++++++ docs/Flutter's-modes.md | 42 +++ docs/Flutter-engine-operation-in-AOT-Mode.md | 75 ++++ docs/Image-Codecs-in-the-Flutter-Engine.md | 11 + docs/JIT-Release-Modes.md | 15 + docs/Life-of-a-Flutter-Frame.md | 62 ++++ docs/README.md | 32 ++ docs/Reduce-Flutter-engine-size-with-MLGO.md | 233 ++++++++++++ docs/Supporting-legacy-platforms.md | 28 ++ ...t-Engine-PRs-with-the-Flutter-framework.md | 48 +++ ...sing-Sanitizers-with-the-Flutter-Engine.md | 125 +++++++ ...-with-a-custom-Flutter-Engine-Embedding.md | 61 +++ .../Comparing-AOT-Snapshot-Sizes.md | 90 +++++ docs/ci/Engine-Clang-Tidy-Linter.md | 56 +++ .../ci/Engine-pre-submits-and-post-submits.md | 79 ++++ docs/contributing/Compiling-the-engine.md | 330 +++++++++++++++++ ...g-up-the-Engine-development-environment.md | 176 +++++++++ docs/impeller/Flutter-GPU.md | 49 +++ docs/impeller/Impeller-Scene.md | 19 + docs/impeller/README.md | 7 + ...tting-up-MoltenVK-on-macOS-for-Impeller.md | 7 + docs/release/Code-signing-metadata.md | 196 ++++++++++ docs/testing/Testing-the-engine.md | 350 ++++++++++++++++++ 28 files changed, 2763 insertions(+) create mode 100644 docs/Crashes.md create mode 100644 docs/Custom-Flutter-Engine-Embedders.md create mode 100644 docs/Custom-Flutter-Engine-Embedding-in-AOT-Mode.md create mode 100644 docs/Debugging-the-engine.md create mode 100644 docs/Engine-disk-footprint.md create mode 100644 docs/Engine-specific-Service-Protocol-extensions.md create mode 100644 docs/Flutter's-modes.md create mode 100644 docs/Flutter-engine-operation-in-AOT-Mode.md create mode 100644 docs/Image-Codecs-in-the-Flutter-Engine.md create mode 100644 docs/JIT-Release-Modes.md create mode 100644 docs/Life-of-a-Flutter-Frame.md create mode 100644 docs/README.md create mode 100644 docs/Reduce-Flutter-engine-size-with-MLGO.md create mode 100644 docs/Supporting-legacy-platforms.md create mode 100644 docs/Testing-presubmit-Engine-PRs-with-the-Flutter-framework.md create mode 100644 docs/Using-Sanitizers-with-the-Flutter-Engine.md create mode 100644 docs/Using-the-Dart-Development-Service-(DDS)-and-Flutter-DevTools-with-a-custom-Flutter-Engine-Embedding.md create mode 100644 docs/benchmarks/Comparing-AOT-Snapshot-Sizes.md create mode 100644 docs/ci/Engine-Clang-Tidy-Linter.md create mode 100644 docs/ci/Engine-pre-submits-and-post-submits.md create mode 100644 docs/contributing/Compiling-the-engine.md create mode 100644 docs/contributing/Setting-up-the-Engine-development-environment.md create mode 100644 docs/impeller/Flutter-GPU.md create mode 100644 docs/impeller/Impeller-Scene.md create mode 100644 docs/impeller/README.md create mode 100644 docs/impeller/Setting-up-MoltenVK-on-macOS-for-Impeller.md create mode 100644 docs/release/Code-signing-metadata.md create mode 100644 docs/testing/Testing-the-engine.md diff --git a/docs/Crashes.md b/docs/Crashes.md new file mode 100644 index 0000000000000..3d20b20b85fd5 --- /dev/null +++ b/docs/Crashes.md @@ -0,0 +1,134 @@ +## Symbolicating stack traces for engine crashes + +The easiest way to symbolicate stack traces for Android and iOS is running the [dart_ci symbolizer locally](https://github.com/dart-lang/dart_ci/blob/main/github-label-notifier/symbolizer/README.md#using-this-locally). If that is not an option, the steps below explain how to do it manually. + +### Android + +#### Get the symbols + +1. Get the Flutter Framework or Flutter Engine revision from the report. If you have the Engine revision, skip to step 3. + +2. Get the Engine revision from the Framework (this could be automated). https://github.com/flutter/flutter/blob/main/bin/internal/engine.version is the file which contains the information. Substitute the framework hash for `main` in that url. + +3. With the full engine revision (e.g. cea5ed2b9be42a981eac762af3664e4a17d0a53f), you can now get the proper symbol files: + + To view the available artifacts for a build, visit this URL in a browser (replacing the engine hash with your hash): `https://console.cloud.google.com/storage/browser/flutter_infra_release/flutter/cea5ed2b9be42a981eac762af3664e4a17d0a53f` + + To download the symbols for android-arm, download this URL _using your browser_ (replacing the hash again, and noting that this URL is on a different host, "storage", compared to the one above, which uses "console"): `https://storage.cloud.google.com/flutter_infra_release/flutter/cea5ed2b9be42a981eac762af3664e4a17d0a53f/android-arm/symbols.zip`. + + Please be aware that the type of the symbol must match your Apps release type. In above example, this refers to a android-arm **debug** build. If you work with a **release** or **profile** build, the URLs would look like this: + + * https://storage.cloud.google.com/flutter_infra_release/flutter/cea5ed2b9be42a981eac762af3664e4a17d0a53f/android-arm-release/symbols.zip + * https://storage.cloud.google.com/flutter_infra_release/flutter/cea5ed2b9be42a981eac762af3664e4a17d0a53f/android-arm-profile/symbols.zip + + You have to use your browser because it does authentication. + +#### Symbolicate with ndk-stack + +Once you have the symbols unzipped, you can use ndk-stack from your Android NDK. Suppose `stack.txt` contains the stack (including the leading `*** *** ***` line from the crash): + +```bash +.../ndk/prebuilt/linux-x86_64/bin/ndk-stack -sym .../path/to/downloaded/symbols < stack.txt +``` + +Or on macOS: +```bash +.../ndk/prebuilt/darwin-x86_64/bin/ndk-stack -sym .../path/to/downloaded/symbols < stack.txt +``` + +Some debugging tools, like _pidcat_ may not show the full tombstone logs. In that case, please use `adb logcat` directly and copy the full output. + +#### Symbolicate with addr2line + +A alternative way to symbolicate is by using the addr2line tool. It is bundled with the NDK. +To use it, simply call it with a path to the .so file downloaded above and feed the stack addresses to it manually. For example, on macOS: + +``` +% $ANDROID_HOME/ndk/20.0.5594570/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line -e ~/Downloads/libflutter.so +``` +_The tool is now awaiting your input, so let's feed it a memory address_: +``` +0x00000000006a26ec +/b/s/w/ir/cache/builder/src/out/android_release_arm64/../../third_party/dart/runtime/vm/dart_api_impl.cc:1366 +``` +This revealed address `0x00000000006a26ec` to correspond with `dart_api_impl.cc:1366`. + +#### Making sure you got the right libflutter.so + +The build system sets a build id for each `libflutter.so` file. In the tombstones, you would see the ID like so: + +``` +#00 pc 000000000062d6e0 /data/app/com.app-tARy3eLH2Y-QN8J0d0WFog==/lib/arm64/libflutter.so!libflutter.so (offset 0x270000) (BuildId: 34ad5bdf0830d77a) +``` + +This equals to a build id of **34ad5bdf0830d77a**. The `libflutter.so` debug files downloaded as shown above could be verified using the `file` command: + +``` +% file ~/Downloads/libflutter.so +/Users/user/Downloads/libflutter.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[xxHash]=34ad5bdf0830d77a, with debug_info, not stripped +``` + +Ensure the build IDs match, else you will not be able to symbolicate. + +#### Expanding Git Revisions + +Go to a commit page with the short commit as the last fragment of the URL: +(e.g. https://github.com/flutter/flutter/commit/9cb914df1 or https://github.com/flutter/engine/commit/2a13567) and then find the full revision on the page. + + +#### Symbolicating local builds + +If you have made your own builds, you can use ndk-stack directly: + +```bash +# dev/engine is where your engine's .gclient file is +# android_debug_unopt is whatever build of your engine you are using +adb logcat | ~/dev/engine/src/third_party/android_tools/ndk/prebuilt/linux-x86_64/bin/ndk-stack -sym ~/dev/engine/src/out/android_debug_unopt +``` + +### iOS + +The dSYM file for `Flutter.framework` (which is the Flutter Engine) for ios-release builds can be downloaded from Google Cloud Storage. Follow the steps from the Android section in this guide, but in the last step use a download url following this schema: `https://storage.cloud.google.com/flutter_infra_release/flutter/38a646e14cc25f5a56a989c6a5787bf74e0ea386/ios-release/Flutter.dSYM.zip` (replace the engine hash with your hash). + +#### Symbolicating local builds + +If you built your local engine in debug or profile Dart modes, the framework's dylib's symbols aren't stripped and are available by default. + +#### Crashes in Dart AOT code + +If the crash is in AOT Dart code (in `--release` or `--profile` builds) on iOS, and you can build your own engine, these steps will be helpful for the VM team to fix the bug: + +* Prepare a reduced test case. +* Compile the engine in profile mode and disable optimizations for symbolicated traces. + * `sky/tools/gn --ios --unopt --runtime-mode profile; ninja -C out/ios_profile_unopt -j800`. +* Launch the application via the Xcode project and make it crash in the debugger. +* File a bug on [dart-lang/sdk](https://github.com/dart-lang/sdk/issues/new). +* Dump the register state and paste it into the bug. + * In `lldb`, `register read`. +* Copy the backtrace and paste it into the bug. + * In `lldb`, `thread backtrace`. Assumes you are on the thread that crashed. If not, `thread select n`. +* Disassemble the last frame and paste it into the bug. + * In `lldb`, `frame select 0` then `disassemble --frame`. +* Disassemble using the `gen_snapshot` and paste the function into the bug for more detailed information. + * In the backtrace, look for the name of the precompiled function that caused the crash. + * Open `SnapshotterInvoke` from Xcode and to the `RunCommand ... Snapshotter` call, add the `--disassemble` flags. + * Modify the `RunCommand` function to dump to a file. + * Build again. The results should end up in the file. + * Look for the function name (by substring match) in this file and copy out that information to the bug. +* Ping someone on dart-lang/sdk. + + +### Android Local Engine Builds + +When running with a local engine build, the symbolization workflow can be cumbersome and unecessary. Instead, it is possible to build the engine itself with symbols and disable Gradle's automatic symbol stripping. This is also required to see symbol names in Android Studio CPU profiles. + +1. In the android engine configuration, provide a --no-stripped argument to gn. For example: `gn --android --android-cpu=arm64 --unopt --no-stripped` + +2. In the flutter project file `android/app/build.gradle`, add the following line under the `android` block: + +``` + packagingOptions{ + doNotStrip "**/*.so" + } + +``` diff --git a/docs/Custom-Flutter-Engine-Embedders.md b/docs/Custom-Flutter-Engine-Embedders.md new file mode 100644 index 0000000000000..c4e965b9b0804 --- /dev/null +++ b/docs/Custom-Flutter-Engine-Embedders.md @@ -0,0 +1,23 @@ +The Flutter Engine is window toolkit agnostic. If you want to build Flutter embedders on one of the platforms not supported out of the box (i.e, iOS & Android), this page is for you. + +This is a very low level API and is not suitable for beginners. + +* The window toolkit agnostic component of the Flutter engine is available as a dynamic library in the `flutter_engine` GN target in [`//shell/platform/embedder:flutter_engine`](https://github.com/flutter/engine/blob/080fbcb1759e5916f0d6cdcdfd945c053320e6b3/shell/platform/embedder/BUILD.gn#L51). +* That target must be built as part of the host GN build. Such builds are already available for desktop Linux & Mac. If you want to target another platform, you will have to configure a GN toolchain for the same. +* You may build this target yourself or download the same artifacts uploaded by the buildbots on each commit. + * The Mac buildbot uploads the artifacts to a known location. Access it here [`https://storage.googleapis.com/flutter_infra_release/flutter/FLUTTER_ENGINE/darwin-x64/FlutterEmbedder.framework.zip`](https://storage.googleapis.com/flutter_infra_release/flutter/080fbcb1759e5916f0d6cdcdfd945c053320e6b3/darwin-x64/FlutterEmbedder.framework.zip). + * Replace `FLUTTER_ENGINE` with the SHA of the Flutter engine you wish to use. + * The Linux buildbot uploads the artifacts to a known location. Access it here [`https://storage.googleapis.com/flutter_infra_release/flutter/FLUTTER_ENGINE/linux-x64/linux-x64-embedder`](https://storage.googleapis.com/flutter_infra_release/flutter/080fbcb1759e5916f0d6cdcdfd945c053320e6b3/linux-x64/linux-x64-embedder) + * Replace `FLUTTER_ENGINE` with the SHA of the Flutter engine you wish to use. + * The binary is not stripped and contains debug information. Embedders are advised to strip the binary before deployment. + * The Windows buildbot uploads the artifacts to a known location. Access it here [`https://storage.googleapis.com/flutter_infra_release/flutter/FLUTTER_ENGINE/windows-x64/windows-x64-embedder.zip`](https://storage.googleapis.com/flutter_infra_release/flutter/080fbcb1759e5916f0d6cdcdfd945c053320e6b3/windows-x64/windows-x64-embedder.zip) + * Replace `FLUTTER_ENGINE` with the SHA of the Flutter engine you wish to use. + * You can also obtain that SHA from the [`engine.version`](https://github.com/flutter/flutter/blob/main/bin/internal/engine.version) file in your Flutter framework checkout. This allows you to exactly match the engine version with the Flutter framework version. +* The Flutter engine API has no platform specific dependencies, has a stable ABI and is available in its entirety in a [single C header file available here](https://github.com/flutter/engine/blob/main/shell/platform/embedder/embedder.h). +* To use as a guide, you may use [this example embedder that uses GLFW](https://github.com/flutter/engine/blob/main/examples/glfw/FlutterEmbedderGLFW.cc) for window management and rendering. + +While we do not object to teams creating custom builds of the Flutter engine for their purposes, we do not support this configuration. Not supporting it means that we do not commit to any timelines for fixing bugs that may come up in such a configuration, even for customers for which we would usually be willing to make commitments (see the [Issue Hygiene](../contributing/issue_hygiene/README.md) page). It also means that we encourage teams to view such configurations as short-term solutions only and encourage teams to transition away from such configurations at the earliest possible opportunity. + +We do not expect custom engine builds to be long-term sustainable. They are not supported on any platform where we plan to be the publisher of a Flutter runtime distinct from the applications that run on the runtime, and they require significant effort to port to our new target platforms such as Web and desktop. There is also an expensive maintenance burden (for example, if we add new features, a custom engine build would need to be updated to support that feature). + +We would generally recommend using custom engine builds only when porting Flutter to platforms that are not supported out of the box, for example in embedded hardware. \ No newline at end of file diff --git a/docs/Custom-Flutter-Engine-Embedding-in-AOT-Mode.md b/docs/Custom-Flutter-Engine-Embedding-in-AOT-Mode.md new file mode 100644 index 0000000000000..64f181c9a9cc1 --- /dev/null +++ b/docs/Custom-Flutter-Engine-Embedding-in-AOT-Mode.md @@ -0,0 +1,132 @@ +This document is intended for developers of third party embedders who wish to package and ship their Flutter applications for AOT mode operation. A third party embedder uses [the stable C embedder API](https://github.com/flutter/engine/blob/869d9f528503778be1e5ab27ba53502f0cb20de2/shell/platform/embedder/embedder.h) to embed Flutter applications on their platform. + +## Building an AOT Flutter Engine + +By default, the Flutter engine packaged for embedders assumes that the mode of operation is JIT. An engine configured for JIT packages a VM that is incompatible with AOT snapshots. Build an AOT engine using the following invocation. This is also the invocation where custom target, sysroot and toolchain selection flags can be specified. + +``` +./flutter/tools/gn --runtime-mode release +``` + +**Note:** Throughout this document, the `gn` flags mentioned work fine with other non-runtime mode or configuration selection options (stuff like `--no-lto`,` --unoptimized`, etc..). Such options are particularly useful during development and their use is highly encouraged. + +This will produce a Flutter engine configured for AOT mode targeting the host. Note that we are repurposing Flutter’s “release” mode policy to prepare an AOT engine. The application of this policy to third party embedders is optional and a decision the authors of such embedders need to make themselves. + +## Building the Architecture Specific `gen_snapshot` + +The binary that converts Dart code to architecture specific AOT instructions is called `gen_snapshot`. A successful invocation of `gen_snapshot` should produce four binary blobs. These are the Dart VM heap and instructions snapshots as well as the isolate heap and instruction snapshots. Refer to the [wiki article on engine operation in AOT mode](Flutter-engine-operation-in-AOT-Mode.md) for the purpose of these snapshots. + +A specific `gen_snapshot` can only produce AOT instructions for one target architecture. To verify that the `gen_snapshot` you have is producing instructions for the architecture you care about, invoke the same with the `--version` flag. It should produce something like the following. + +``` +Dart VM version: 2.1.1-dev.2.0.flutter-ac1bf656c4 (Thu Jan 17 16:55:19 2019 +0000) on "macos_x64" +``` + +The final string denotes the host/target pair. In the case of the example above, the host is `macos` and the target `x64`. An example of a `gen_snapshot` that produces instructions for `aarch64` would read “macos_simarm64” (the author is on MacOS X). + +It is easiest to just pick the supported Flutter target whose architecture is closest to the one of the embedder. For example, if the target is `armv7`, the following invocation will generate a `gen_snapshot` that is suitably configured for that target. + +``` +./flutter/tools/gn --android --runtime-mode release +``` + +Another useful invocation for aarch64 AOT targeted `gen_snapshot` is: + +``` +./flutter/tools/gn --android --runtime-mode release --android-cpu arm64 +``` + +**Important:** Calling convention and alignment must be the same (in addition to just the target architecture) for the AOT instructions generated by `gen_snapshot` and the target. Repurposing Flutter’s build targets makes sure that all those subtleties are taken care of. But it is still up to the embedder to pick and match the AOT instructions. For example, the `--android` --android-cpu arm64`configured`gen_snapshot`will not generate completely compatible instructions for iOS on`aarch64` (even though the target architectures are the same). A mismatch between the snapshot's architecture/ABI and the device's architecture/ABI will be detected when the snapshot is loaded and clearly reported. + +## Building the AOT Snapshot + +There are two separate steps involved in the generation of AOT instructions for the target architecture. First, a target architecture agnostic kernel snapshot (~AST) of the Flutter Dart application needs to be generated. Then, this snapshot is given to `gen_snaphost` which generates the AOT snapshot in the form of the four blobs (~machine code) listed above (and detailed on the wiki page). + +### The Short and Easy Way + +Both iOS and Android AOT modes need to do this step when they build their artifacts. So, if the embedder targets are similar, the workflow supported by the Flutter tooling can be repurposed for custom AOT embedders. For example, in the case of `aarch64` AOT instructions for Android like targets, the following instructions will generated the four AOT blobs in the intermediates. + +```bash +flutter --local-engine --local-engine-host build aot --target-platform android-arm64 --release +``` + +**Note:** The `--local-engine` (and `--local-engine-host`) flag is technically optional. However, not specifying the flag will make the tools pick the released version on of the Flutter engine. This version may contain subtle version mismatches with the engine you are using to prepare the `gen_snapshot` binary. So it is safer to just make sure the version are the same. +See [running with a local engine](Debugging-the-engine.md#running-a-flutter-app-with-a-local-engine) for more details. + +The result of the invocation will be the generation of the following binary blobs in the `build/aot directory`: + +- `vm_snapshot_data`: The VM snapshot data. +- `vm_snapshot_instr`: The VM snapshot instructions. +- `isolate_snapshot_data`: The Isolate snapshot data. +- `isolate_snapshot_instr`: The isolate snapshot instructions. + +### The Hard Way + +To generate the four AOT snapshot blobs directly, you will have to generate the kernel snapshot and then prepare the AOT snapshot manually. The exact flags to use are rather esoteric but self explanatory. And, when necessary, the `-v` flag can be passed to the `flutter build aot` instruction to dump the exact flags used by Flutter. These can then be modified as necessary for the target architecture. + +#### Generating the Kernel Snapshot + +The following invocation will generate a file called `kernel_snapshot.dill` in the build directory. Make sure you run `flutter packages get` in your project first to fetch all package dependencies. + +``` +$FLUTTER_ENGINE_OUT_DIR/dart \ + $FLUTTER_ENGINE_OUT_DIR/frontend_server.dart.snapshot \ + --sdk-root $FLUTTER_ENGINE_OUT_DIR/flutter_patched_sdk/ \ + --strong \ + --target=flutter \ + --aot \ + --tfa \ + -Ddart.vm.product=true \ + --packages .packages \ + --output-dill build/kernel_snapshot.dill \ + package:flutter_gallery/main.dart +``` + +#### Generating the AOT Snapshot + +Once the `kernel_snapshot.dill` file has been obtained, `gen_snapshot` can be invoked with the following arguments to generate the four blobs that form the AOT snapshot. + +``` +$FLUTTER_ENGINE_OUT_DIR/gen_snapshot \ + --causal_async_stacks \ + --packages=.packages \ + --deterministic \ + --snapshot_kind=app-aot-blobs \ + --vm_snapshot_data=build/vm_snapshot_data \ + --isolate_snapshot_data=build/isolate_snapshot_data \ + --vm_snapshot_instructions=build/vm_snapshot_instr \ + --isolate_snapshot_instructions=build/isolate_snapshot_instr \ + --no-sim-use-hardfp \ + --no-use-integer-division \ + build/kernel_snapshot.dill +``` + +**Note:** The `-no*` flags in the invocation above may not be necessary for all targets and can be skipped. As always, when in doubt, call `flutter build aot -v` after selecting the most similar target and see the flags used by Flutter. + +## Packaging the AOT Blobs + +The four AOT blobs need to be shipped with the application and are necessary for the `FlutterEngineRun` call. Embedders have to make a decision about how best to package and ship these blobs to the target. + +On the target at runtime, these blobs need to be mapped into the address space with the following restrictions: + +- `vm_snapshot_data`: Read-Only. +- `vm_snapshot_instr`: Read-Execute. +- `isolate_snapshot_data`: Read-Only. +- `isolate_snapshot_instr`: Read-Execute. + +The responsibility of keeping the mappings alive is upto the embedder. The mappings must be maintained as long as the `FlutterEngine` is running and alive. + +## Configuring the Engine for AOT Operation + +In the `FlutterProjectArgs` struct given the `FlutterEngineRun` call, provide the following options: + +- `vm_snapshot_data`: Pointer to the read-only VM snapshot mapping. +- `vm_snapshot_data_size`: Size of the VM snapshot mapping. +- `vm_snapshot_instructions`: Pointer to the read-execute VM instructions mapping. +- `vm_snapshot_instructions_size`: Size of the VM instructions mapping. +- `isolate_snapshot_data`: Pointer to the read-only isolate snapshot mapping. +- `isolate_snapshot_data_size`: Size of the isolate snapshot mapping. +- `isolate_snapshot_instructions`: Pointer to the read-execute isolate instructions mapping. +- `isolate_snapshot_instructions_size`: Size of the isolate instructions mapping. + +Flutter Engine is now running in AOT mode! diff --git a/docs/Debugging-the-engine.md b/docs/Debugging-the-engine.md new file mode 100644 index 0000000000000..7dad334547035 --- /dev/null +++ b/docs/Debugging-the-engine.md @@ -0,0 +1,147 @@ +This page has some hints about debugging the engine. + +See also [Crashes](Crashes.md) for advice on handling engine crashes (specifically around obtaining stack traces, and reporting crashes in AOT Dart code). + +## Running a Flutter app with a local engine + +First, make sure the appropriate version of the engine is built (see [Compiling the engine](./contributing/Compiling-the-engine.md)). + +### Using the Flutter tool + +Run your Flutter app with: + +```bash +flutter run --local-engine=XXXX --local-engine-host=YYYY +``` + +to run an app with the local engine where `XXXX` should be replaced with the version you wish to use. For example, use `--local-engine=android_debug_unopt --local-engine-host=host_debug_unopt` to run a debug android engine or `--local-engine=ios_debug_sim_unopt --local-engine-host=host_debug_unopt` to run a debug iOS simulator engine. + +> 💡 **TIP**: When developing on a Mac with ARM (M CPU), use `--local-engine-host=host_debug_unopt_arm64`. +> +> You can continue to use `host_debug_unopt` (required for Intel Macs), but the engine will be run under Rosetta +> which may be slower. See [Developing with Flutter on Apple Silicon](../platforms/desktop/macos/Developing-with-Flutter-on-Apple-Silicon.md) +> for more information. + + +It is important to always have a `host_XXXX` version of the engine built when using a local engine since Flutter uses the host build's version of Dart. + +### Using Visual Studio Code + +You will need to add a new [launch configuration](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations) in the `launch.json` file: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch (local engine)", + "request": "launch", + "type": "dart", + "args": ["--local-engine", "XXX", "--local-engine-host", "YYY"] + } + + // Other profiles below.. + ] +} +``` + +## Bisecting a roll failure + +If the engine roll is failing (see [Autorollers](../infra/Autorollers.md)), you can use `git bisect` on the engine repo to track down the offending commit, using the `--local-engine` and `--local-engine-host` arguments as described above to run the failing framework test with each version of the engine. + +## Tracing OpenGL calls in Skia + +All OpenGL calls in Skia are guarded by either the `GR_GL_CALL_NOERRCHECK` or `GR_GL_CALL_RET_NOERRCHECK` macros. Trace events may be added in these macros to trace all GL calls made by Skia, for example [in a patch like this](https://gist.github.com/chinmaygarde/607eb86d5447615b9cf2804a4f8fb1ce). + +Due to the number of events traced to the timeline, the trace buffer may be filled up very quickly. Unless you want to see only the traces for the past few frames, use an endless trace buffer (`flutter run --endless-trace-buffer` turns on an endless trace buffer). + +Also, make sure to run your application with the `--trace-skia` flag. + +## Debugging iOS builds with Xcode + +Building with `flutter --local-engine` will set a `LOCAL_ENGINE` Xcode build setting in your Flutter application's `ios/Flutter/Generated.xcconfig` file. This will be set until you run `flutter run` again with either a different `--local-engine` option, or with none at all (which will unset it). + +You can speed up your workflow by adding the `--config-only` flag to set up the Xcode build settings and plugins, but not compile the app. For example: + +```bash +flutter build ios --local-engine ios_debug_unopt --local-engine-host host_debug_unopt --config-only +``` + +To start debugging, open your Flutter app `ios/Runner.xcworkspace` file in Xcode. Ensure **Product > Scheme > Edit Scheme > Run > Build Configuration** matches your engine runtime mode (defaults to `Debug`). + +Product > Scheme > Edit Scheme > Run > Build Configuration + +Add an engine symbol breakpoint via **Debug > Breakpoints > Create Symbolic Breakpoint...**. The **Symbol** field should be the engine symbol you're interested in, like `-[FlutterEngine runWithEntrypoint:]` (note the `-[` prefix has no space). + +You can also set a breakpoint directly with [lldb](https://lldb.llvm.org/tutorial.html) by expanding **Flutter > Runner** in the Runner Project Navigator. Put a breakpoint in `AppDelegate.swift`'s `application(didFinishLaunchingWithOptions:)` (Swift project) or `main.m`'s `main()` (Objective-C project) and start the application by clicking the Run button (CMD + R). Then, set your desired breakpoint in the engine in `lldb` via `breakpoint set -...`. + +## Debugging Android builds with gdb + +See https://github.com/flutter/engine/blob/main/sky/tools/flutter_gdb#L13 + +## Debugging native engine code on Android with Android Studio + +1. Build the local engine with the `--no-stripped` flag. +2. Decide on a Flutter app that you with to debug and run it with `flutter run` and the local engine flags. i.e.: `--debug --local-engine-src-path path/to/my/engine/src --local-engine=android_debug_unopt_arm64` +3. Open Android Studio and use `File > Profile or Debug APK`. The location of the debug build APK should be `build/app/outputs/apk/debug/app-debug.apk` under the Flutter app project. +4. To attach the debugger, use `Run > Attach Debugger to Android Process`. For "Use Android Debugger Settings from" choose `[Use default settings]`, and for "Debug Type" choose `Native Only`. +5. Once attached, you can use Android Studio to open local engine C++ source files and set breakpoints. + +## Debugging Windows builds with Visual Studio + +Compiling the engine creates a Visual Studio solution file. You can use it to debug the engine: + +1. Launch your Flutter app using a locally built engine `flutter run -d windows --local-engine host_debug_unopt --local-engine-host host_debug_unopt` +2. Using Visual Studio, open the engine's solution file `.\out\host_debug_unopt\all.sln` +3. Open `Debug` > `Attach to Process...` (or press `CTRL+ALT+P`) +4. Choose your Flutter app using either `Select Window`, or, the list of available processes. +5. Press the `Attach` button + +Building a Flutter app also creates a Visual Studio solution file. You can use it to debug the +engine, your app's runner, and your app's plugins: + +1. Build your Flutter app using a locally built engine using `flutter build windows --debug --local-engine host_debug_unopt --local-engine-host host_debug_unopt` +2. Using Visual Studio, open the Flutter app's `.\build\windows\.sln` +3. In the `Solution Explorer` pane, right click the project whose name matches your app, and select `Set as Startup Project` + + ![Set as Startup Project example](https://user-images.githubusercontent.com/737941/215009513-d31c59fd-1f54-44d9-a702-6dd3fdf71492.png) + +4. Now run your app by pressing `F5` or `DEBUG` > `Start Debugging`. This will launch your app with Visual Studio's debugger attached. + +Read this guide to [learn how to debug C++ using Visual Studio](https://learn.microsoft.com/visualstudio/debugger/getting-started-with-the-debugger-cpp?view=vs-2022). + +## Debugging with gdb on Linux + +Once you have built the engine, you'll find the unstripped libraries in `out/host_debug_unopt/lib.unstripped`, and the executables in `out/host_debug_unopt/exe.unstripped`. + +So, for instance, to run the unit tests under the debugger you would execute: + +```shell +flutter/tools/gn --runtime-mode=debug --unoptimized +ninja -C out/host_debug_unopt +gdb out/host_debug_unopt/exe.unstripped/flutter_linux_unittests +``` + +And then debug the test normally using GDB commands. + +To debug a Flutter app using GDB, the stripped flutter engine GTK library in the built application needs to be replaced with the unstripped one in the engine build output directory. + +First, in your Flutter project, build your Flutter app using the local engine: + +```shell +flutter build linux --debug --local-engine=host_debug_unopt --local-engine-host=host_debug_unopt lib/main.dart +``` + +Then, replace the library in your Flutter application's build directory: `build/linux/x64/debug/bundle/lib/libflutter_linux_gtk.so` with a copy or symbolic link to the engine build's output file `out/host_debug_unopt/lib.unstripped/libflutter_linux_gtk.so`. + +Then you can open it in the debugger with: + +```shell +gdb build/linux/x64/debug/bundle/your_app_name +``` + +Note that this won't help you debug the Dart portion of the app: this is just for debugging the engine code. If you need to simultaneously debug the Dart portion, you can connect to the observatory port given when you run the app in `gdb`. + +## Logging in the engine + +Flutter tool will by default parse out any non-error output from the engine. Error logs will be displayed. Logging is handled though the FML library's `logging.h`. diff --git a/docs/Engine-disk-footprint.md b/docs/Engine-disk-footprint.md new file mode 100644 index 0000000000000..0ce647128c755 --- /dev/null +++ b/docs/Engine-disk-footprint.md @@ -0,0 +1,33 @@ +## Treemaps + +For each commit to [flutter/engine](https://github.com/flutter/engine) the Chromebots generate treemaps illustrating the sizes of the individual components within release builds of `libflutter.so`. The treemap is uploaded to Google Cloud Storage and linked from the [LUCI](https://ci.chromium.org/p/flutter/g/engine/console) console: Select a "Linux aot" build and search for "Open Treemap". + +Alternatively, a link to a treemap can be constructed as follows: + +`https://storage.googleapis.com/flutter_infra_release/flutter///sizes/index.html` where: +* `` is the git hash from [flutter/engine](https://github.com/flutter/engine) for which you want the treemap, and +* `` can be any android release build, e.g. `android-arm-release` or `android-arm64-release`. + +## Benchmarks + +In [devicelab](https://github.com/flutter/flutter/tree/main/dev/devicelab) we run various benchmarks to track the APK/IPA sizes and various (engine) artifacts contained within. These benchmarks run for every commit to [flutter/flutter](https://github.com/flutter/flutter) and are visible on our [build dashboard](https://flutter-dashboard.appspot.com/). The most relevant benchmarks for engine size are: + +* APK/IPA size of Flutter Gallery + * Android: `flutter_gallery_android__compile/release_size_bytes` + * iOS: `flutter_gallery_ios__compile/release_size_bytes` +* APK/IPA size of minimal hello_world app + * Android: `hello_world_android__compile/release_size_bytes` + * iOS: `hello_world_ios__compile/release_size_bytes` +* Size of bundled `icudtl.dat` + * Compressed in APK: `hello_world_android__compile/icudtl_compressed_bytes` + * Uncompressed: `hello_world_android__compile/icudtl_uncompressed_bytes` +* Size of bundled `libflutter.so` (release mode) + * Compressed in APK: `hello_world_android__compile/libflutter_compressed_bytes` + * Uncompressed: `hello_world_android__compile/libflutter_uncompressed_bytes` +* Size of VM & isolate snapshots (data and instructions) + * Compressed in APK: `hello_world_android__compile/snapshot_compressed_bytes` + * Uncompressed: `hello_world_android__compile/snapshot_uncompressed_bytes` + +## Comparing AOT Snapshot Sizes + +A detailed comparison of AOT snapshot sizes can be performed using the [instructions documented here](./benchmarks/Comparing-AOT-Snapshot-Sizes.md). \ No newline at end of file diff --git a/docs/Engine-specific-Service-Protocol-extensions.md b/docs/Engine-specific-Service-Protocol-extensions.md new file mode 100644 index 0000000000000..73e5b28fcd623 --- /dev/null +++ b/docs/Engine-specific-Service-Protocol-extensions.md @@ -0,0 +1,203 @@ +The Flutter engine adds several extensions to the [Dart VM Service Protocol](https://github.com/dart-lang/sdk/blob/main/runtime/vm/service/service.md). The Flutter Engine specific extensions are documented here. Applications may also choose to register their [own extensions](https://api.dartlang.org/stable/1.24.3/dart-developer/registerExtension.html). + +## List views: `_flutter.listViews` + +Tooling requests this very early in the application lifecycle to ask for the details of the root isolate. + +No arguments. + +Response: + +```json +{ + "type": "FlutterViewList", + "views": [ + { + "type": "FlutterView", + "id": "_flutterView/0x1066096d8", + "isolate": { + "type": "@Isolate", + "fixedId": true, + "id": "isolates/453229818", + "name": "main.dart$main-453229818", + "number": 453229818 + } + } + ] +} +``` + +## Isolate Restart or Cold Reload: `_flutter.runInView` + +The IDE has requested (or the user pressed ‘R’ from the ‘flutter run’ interactive console) a cold reload. For example, this happens when the user presses the green play button. + +Used to "cold reload" a running application where the shell (along with the platform view and its rasterizer bindings) remains the same but the root isolate is torn down and restarted with the new configuration. Only used in the development workflow. + +The previous root isolate is killed and its identifier invalidated after this call. Callers can query the new isolate identifier using the `_flutter.listViews` method. + +Four arguments: + +``` +viewId = _flutterView/0x14ba08c68 +mainScript = /path/to/application/lib/main.dart +packagesFile = /path/to/application/.packages +assetDirectory = /path/to/application/build/flutter_assets +``` + +Response: + +```json +{ + "type": "Success", + "view": { + "type": "FlutterView", + "id": "_flutterView/0x104e0ab58", + "isolate": { + "type": "@Isolate", + "fixedId": true, + "id": "isolates/1056589762", + "name": "main.dart$main-1056589762", + "number": 1056589762 + } + } +} +``` + +The object in the **view** key is constructed in the same way as the views in the **List Views** method. + + +## Flush UI thread tasks: `_flutter.flushUIThreadTasks` + +Does nothing but waits for all pending tasks on the UI thread to be completed before returning success to the service protocol caller. + +No arguments. + +Response: + +```json +{"type": "Success"} +``` + +## Get screenshot of view as PNG: `_flutter.screenshot` + +Get the screenshot as PNG of a random Flutter view on the device. The screenshot data will be base64 encoded in the response body. + +No arguments. + +Response: + +```json +{ + "type": "Screenshot", + "screenshot": "" +} +``` + +## Get screenshot of view as Skia picture: `_flutter.screenshotSkp` + +Get the Skia SKP of a random Flutter view on the device. The SKP data will be base64 encoded in the response body. + +No arguments. + +Response: + +```json +{ + "type": "ScreenshotSkp", + "skp": "" +} +``` + +## Update asset bundle path: `_flutter.setAssetBundlePath` + +In case of a hot-reload, the service protocol handles source code updates. However, there may be changes to assets. The DevFS updates assets in an separate directory that needs to be used by the engine. + +Two arguments: + +``` +viewId = _flutterView/0x15bf057f8 +assetDirectory = /path/to/flutter_assets +``` + +Response: + +```json +{ + "type": "Success", + "view": { + "type": "FlutterView", + "id": "_flutterView/0x104e0ab58", + "isolate": { + "type": "@Isolate", + "fixedId": true, + "id": "isolates/1056589762", + "name": "main.dart$main-1056589762", + "number": 1056589762 + } + } +} +``` + +The object in the **view** key is constructed in the same way as the views in the **List Views** method. + +## Get the display refresh rate: `_flutter.getDisplayRefreshRate` + +Get the display refresh rate of the actual device that runs the Flutter view. For example, most devices would return an fps of 60, while iPad Pro would return an fps of 120. + +One argument: + +``` +viewId = _flutterView/0x15bf057f8 +``` + +Response: + +```json +{ + "type": "DisplayRefreshRate", + "fps": 60.0 +} +``` + +## Get Skia SkSL shader artifacts: `_flutter.getSkSLs` + +Get Skia SkSL shader artifacts from an actual device that runs the Flutter view. Such artifacts can be used to warm up shader compilations and avoid jank. One has to first tell Flutter to prepare SkSL shaders by `flutter run --cache-sksl` or `flutter drive --cache-sksl`, and trigger some shader compilations by going through some animations/transitions. Otherwise, this service protocol extension may return an empty set of SkSLs. + +The key of the returned `SkSLs` map will be Base32 encoded. It should be used directly as the filename of the shader artifact. The value in that map is the Base64 encoded SkSL shader. Once decoded, it should be the content of the shader artifact file. + +One argument: + +``` +viewId = _flutterView/0x15bf057f8 +``` + +Response: + +```json +{ + "type": "GetSkSLs", + "SkSLs": { + "CAZAAAACAAAAAAAAAAABGAABAAOAAFAADQAAGAAQABSQAAAAAAAAAAAAAABAAAAAEAAGGAA": "eQ==" + } +} +``` + +## Estimate raster cache memory usage: `_flutter.estimateRasterCacheMemory` + +Estimate the memory usage of both picture and layer raster cache. For each picture or layer cached, there is a rasterized `SkImage` of that picture or layer to speed up future draws. Only `SkImage`'s memory usage is counted as other objects in the cache system are often much smaller compared to `SkImage`. Function `SkImageInfo::computeMinByteSize` is used to estimate the `SkImage` memory usage. + +One argument + + ``` +viewId = _flutterView/0x15bf057f8 +``` + +Response: + +```json +{ + "type": "EstimateRasterCacheMemory", + "layerBytes": 40000, + "pictureBytes": 400 +} +``` diff --git a/docs/Flutter's-modes.md b/docs/Flutter's-modes.md new file mode 100644 index 0000000000000..5300a72d573ff --- /dev/null +++ b/docs/Flutter's-modes.md @@ -0,0 +1,42 @@ +We aspire to reach a state where developers are able to use the following modes for running Flutter code. Our tools should not expose any other combinations of features or modes. Each mode corresponds to a separate build of the engine that we provide. + +1. **Debug** mode on device (including simulators, emulators): Turns on all the assertions in the world, includes all debugging information, enables all the debugger aids (e.g. observatory) and service extensions. Optimizes for fast develop/run cycles. Does not optimize for execution speed, binary size, or deployment. Used by `flutter run`. Built with `sky/tools/gn --android` or `sky/tools/gn --ios`. Also sometimes called "**checked** mode" or "**slow** mode". + +2. **Release** mode on device (excluding simulators, emulators): Turns off all assertions, strips as much debugging information as possible, turns off all the debugger tools. Optimizes for fast startup, fast execution, small package sizes. Disables any debugging aids. Disables service extensions. Intended for deployment to end-users. Used by `flutter run --release`. Built with `sky/tools/gn --android --runtime-mode=release` or `sky/tools/gn --ios --runtime-mode=release`. + +3. **Profile** mode on device (excluding simulators, emulators): Same as release mode except that profile-mode service extensions (like the one that turns on the performance overlay) is enabled, and tracing is enabled, as well as the minimum required to support using the tracing information (e.g. observatory can probably connect to the process). Used by `flutter run --profile`. Built with `sky/tools/gn --android --runtime-mode=profile` or `sky/tools/gn --ios --runtime-mode=profile`. Not available on simulators or emulators because profiling on simulators is not representative of real performance. + +4. Headless **test** mode on desktop: Same as debug mode except headless and for desktop platforms. Used by `flutter test`. Built with `sky/tools/gn`. + +In addition, for our purposes during development, each of the above should be able to be built in two modes: optimized, which is what end-developers use, and unoptimized, which is what we would use when debugging the engine. Optimized is the default, unoptimized engines are built by adding `--unoptimized` to the arguments. + + +### Artifact differences + +Debug mode produces a script snapshot, which is basically tokenized sources. Comments and whitespace are missing, literals are canonicalized. There is no machine code, tree-shaking or obfuscation. + +Profile and release modes produce app-aot snapshots, either as dylibs (iOS and Fuchsia) or 4-tuples of blobs (Android). Both include machine code for all the compiled functions, code metadata, method dictionaries, class and library structures, types, etc. The machine code is fully position-independent. The dylib additionally has DWARF debug info such as function names and source positions. There is tree-shaking. Obfuscation is opt-in. + +### Matrix + +The following axes, as described above, exist: + +* debug, release, profile +* opt, unopt +* iOS, Android, macOS, Linux, Windows + +In addition, some versions can select alternative graphics backends: + +* iOS can choose between: OpenGL, software +* Android can choose between: Vulkan, OpenGL, software +* macOS can choose between, OpenGL, software, headless (debug only) +* Linux can choose between: OpenGL, software, headless (debug only) +* Windows can choose between: OpenGL, software, headless (debug only) + +Separate from all the above, Fuchsia has the following modes: + +* AOT, JIT, interpreted DBC +* Observatory present, observatory absent +* opt, unopt + +In total therefore there are 3×2×(2+3+2+2+2) + 1×2×3 + 3×2×2 modes, which is 84 modes. diff --git a/docs/Flutter-engine-operation-in-AOT-Mode.md b/docs/Flutter-engine-operation-in-AOT-Mode.md new file mode 100644 index 0000000000000..e232ebf287419 --- /dev/null +++ b/docs/Flutter-engine-operation-in-AOT-Mode.md @@ -0,0 +1,75 @@ +# Overview + +The Flutter Engine in AOT mode requires four artifacts to run any given isolate. These are: + +* **Dart VM Snapshot** + * Represents the initial state of the Dart heap shared between isolates. + * Helps launch Dart isolates faster. + * Does not contain any isolate specific information. + * Mostly predefined Dart strings used by the VM + * Should live in the data segment. + * From the VM's perspective, this just needs to be loaded in memory with READ permissions and does not need WRITE or EXECUTE permissions. Practically this means it should end up in rodata when putting the snapshot in a shared library. +* **Dart VM Instructions** + * Contains AOT instructions for common routines shared between all Dart isolates in the VM. + * This snapshot is typically extremely small and mostly contains stubs. + * Must live in the text segment. +* **Isolate Snapshot** + * Represents the initial state of the Dart heap and includes isolate specific information. + * Along with the VM snapshot, helps in faster launches of the specific isolate. + * Should live in the data segment. +* **Isolate Instructions** + * Contains the AOT code that is executed by the Dart isolate. + * Must live in the text segment. + +The VM snapshot and instructions can be shared between all isolates. These must be available during the initialization of the Dart VM. The Dart VM is initialized when the first Flutter view initializes an instance of the Flutter shell. The Flutter shell manages thread safe initialization of the Dart VM. Once the Dart VM is initialized, multiple instances of the Flutter view reference the same VM to run their isolates. There can only be one VM running in the process at any given time. + +Given this configuration, launching each root isolate (for a Flutter application) requires two artifacts along with two other artifacts that are shared between all the other isolates. + +Isolates launched by Dart code (e.g., Isolate.spawn) inherit the snapshots of their parents. + +# Snapshot Generation + +These artifacts on all platforms are generated by the same binary on the host. This binary is shipped with Flutter tools and is called `gen_snapshot`. The way these artifacts are packed and referenced on the device differs however. + +## iOS Configuration + +`gen_snapshot` is invoked on the host by Xcode to generate the four binary blobs for each artifact. + +Using the native toolchain in Xcode, these artifacts are compiled into a framework bundle that is packaged into the application. This framework is typically called `App.framework` and is present in the `Frameworks/` folder of the application bundle. The name of the framework is configurable and if the embedder wishes to name it anything other than `App.framework`, the embedder can choose a custom name and specify the same in the `FLTLibraryPath` `Info.plist` key for the main application bundle. + +The Flutter engine, itself in a Framework called `Flutter.framework` will dynamically open the resolved application framework and look for four specific symbols in that library. These symbols are called `kDartVmSnapshotData`, `kDartVmSnapshotInstructions`, `kDartIsolateSnapshotData` and `kDartIsolateSnapshotInstructions`. These refer to the four snapshots mentioned above. + +Once snapshot resolution is finalized, the Flutter engine initializes the VM and launched the isolates. + +This configuration was chosen because the Flutter engine is not able to mark pages as executable at runtime. Packaging the instruction in a binary makes sure all instructions are present in a separate dynamic library. This arrangement helps in isolate of code for a specific Flutter view’s root isolate. + +## Android Configuration + +`gen_snapshot` is invoked by Gradle to generate the four binary blobs for each artifact. + +Gradle actually invokes `flutter build aot` under the hood to generate these artifacts. These binary artifacts are packaged into the APK directly. These artifacts are named `vm_snapshot_data`, `vm_snapshot_instr`, `isolate_snapshot_data` and `isolate_snapshot_instr`. They refer to the four snapshots mentioned above. + +The embedder may choose to put these artifacts in custom locations. In such cases, the embedder must place these artifacts in a directory and specify the location using the following 5 flags: + * `aot-snapshot-path`: Path to the directory in the APK assets containing the snapshot. + * `vm-snapshot-data`: Path to the VM snapshot in that directory. + * `vm-snapshot-instr`: Path to the VM instructions in that directory. + * `isolate-snapshot-data`: Path to the isolate snapshot in that directory. + * `isolate-snapshot-instr`: Path to the isolate instructions in that directory. + +Once the Flutter engine, itself packaged as a separate dynamic library called `libflutter.so`, resolves the locations of the required artifacts, it maps them in and makes sure the instructions are executable before launching the VM and isolate. + +The tooling on Android does not require the presence of the Android NDK because the engine can mark pages as executable at runtime. If the embedder wishes to package the snapshots into a single dynamic library (and make the configuration look like the one used on iOS), it can do so and specify the library to the engine via the flag `aot-shared-library-path`. A native toolchain is necessary on the host to achieve this. + +# Notes + +`gen_snapshot` can only generate AOT instructions for a specific architecture. For example, generating AOT instructions for `armv7`, `aarch64`, `i386` and `x86-64` requires four different `gen_snapshot` variants. + +The VM and isolate snapshot data is specific to the `gen_snapshot` variant used and must also be generated along with the AOT instructions. Embedders may not mix and match the AOT instructions and data snapshots from different `gen_snapshot` variants. All four artifacts must typically be generated at the same time. + +Using the current Flutter tools, only an `i386` `gen_snapshot` on the host can generate `armv7` AOT instructions and an `x86-64` `gen_snapshot` on the host can generate `aarch64` instructions. The mac builds take advantage of this quirk and `lipo` the two `gen_snapshot` variants and select the executable architecture correctly when generating AOT instructions for the target architecture. This can be inspected with the `lipo` tool on the host while analyzing the `gen_snapshot` binary. In reality, the word sizes of `gen_snapshot` on host and the engine running on the target must match. Theoretically, an `armv7` `gen_snapshot` running on a Raspberry Pi host could generate an AOT snapshot for `armv7` target. The tools don’t ship this configuration however. + +Packaging multiple Flutter AOT application in the same application bundle will currently result in redundant copies of the VM data and instructions. However, these buffers are extremely small. + +Flags to the Flutter engine are typically specified when the platform launches the underlying Flutter shell (platform agnostic way of interacting with the innards of the Flutter engine). This happens in `FlutterViewController` on iOS and `FlutterNativeView` in Java on Android. + +To list all the flags currently supported by the Flutter engine, embedders may locate the `flutter_tester` binary in the tools distribution and pass the `--help` flag to the same. All currently supported flags along with a short help blob will be dumped to the console. diff --git a/docs/Image-Codecs-in-the-Flutter-Engine.md b/docs/Image-Codecs-in-the-Flutter-Engine.md new file mode 100644 index 0000000000000..4ea514f02e29c --- /dev/null +++ b/docs/Image-Codecs-in-the-Flutter-Engine.md @@ -0,0 +1,11 @@ +# Image Codecs in the Flutter Engine + +Flutter has built-in support for a number of common codecs. Images in the supported formats can be decompressed by the Flutter Engine even if they are not supported by the underlying platform. + +However, each codec supported out-of-the-box by the Flutter Engine adds to the binary size of the engine. Unlike AOT compiled Dart code, this binary size increase cannot be tree shaken away. Every user of the Flutter application will be forced to download the codec irrespective of whether their Flutter applications actually decompress images of that type. Flutter users and developers are extremely sensitive to increases in binary size of the application. + +If the Flutter engine is unable to decompress specific images because it doesn’t support that codec, it will delegate responsibility of image decompression to the platform. This comes in handy if the platform has support for newer or less widely used codecs. The downside of course is that the application author will need to provide an alternative in case both the engine and platform don’t support a specific codec. + +If the application wishes to support a codec that isn’t supported by either the engine or the platform, it will have to ship the codec along with their application and expose its functionality via a plugin. This is more cumbersome but the current recommendation for applications for whom support for specific formats is table stakes. + +Speculatively adding and removing codecs into the Flutter engine may lead to fragmentation in the supported codecs across Flutter engine versions. But, if a format does become widely used, it strengthens the case for adding the codec to the engine in spite of the binary size increase. diff --git a/docs/JIT-Release-Modes.md b/docs/JIT-Release-Modes.md new file mode 100644 index 0000000000000..a6b991b7774a8 --- /dev/null +++ b/docs/JIT-Release-Modes.md @@ -0,0 +1,15 @@ +Normally Flutter runs in JIT for faster compilation/debugging support in `debug` mode and AOT mode for better performance in `profile` and `release` mode. For platforms that Flutter cannot produce AOT artifacts for, such as Android x86 (32 bit), a JIT release build may be used instead. The advantage of this mode over a regular debug build is that it removes debugging support and disables assertions which makes the final artifact smaller and more performant, though less so than a full AOT build. + + +JIT release mode can be used with a local engine configuration. For example, to setup an Android x86 jit_release and host build you can use the GN command below. Both device and host artifacts need to be built, except in cases where they are the same such as the Desktop shells. + +```shell +./flutter/tools/gn --runtime-mode=jit_release --android --android-cpu=x86 +ninja -C out/android_jit_release_x86 +./flutter/tools/gn --runtime-mode=jit_release +ninja -C out/host_jit_release +``` + +This can be used with the flutter tool [via the `--local-engine`](Debugging-the-engine.md#running-a-flutter-app-with-a-local-engine) flag to produce a bundle containing the jit release artifacts using the `flutter assemble` command. By default, flutter.gradle does not know how to package this artifacts so it requires custom integration into a build pipeline. Nevertheless, the artifact structure should be identical to a debug build, but with asserts disabled and product mode enabled. + +jit_release is not supported on iOS devices. Applications built in JIT mode cannot be distributed on the Apple App Store. \ No newline at end of file diff --git a/docs/Life-of-a-Flutter-Frame.md b/docs/Life-of-a-Flutter-Frame.md new file mode 100644 index 0000000000000..e606895351afe --- /dev/null +++ b/docs/Life-of-a-Flutter-Frame.md @@ -0,0 +1,62 @@ +Flutter apps work by transforming the widget tree in an application to a render tree that describes how to graphically render the widgets onscreen, and animating in response to input events or the passage of time. We refer to a single still image within the sequence of images composing an animation as a frame, similar to a frame in a movie filmstrip. In the context of a complete Flutter application these are rendered into a `FlutterView` class which is typically an instance of a platform-specific view class like [SurfaceView][surfaceview] on Android, [UIView][uiview] on iOS, [HWND][hwnd] on Windows, [NSView][nsview] on macOS, or [GtkBox][gtkbox] on Linux. + +This page attempts to describe the life of a Flutter frame in the engine from initial trigger to rasterization, presentation, and finally destruction/recycling. For an overview of the Framework side of this process, see the [Flutter's Rendering Pipeline][renderingPipelineTalk] tech talk. + +[gtkbox]: https://docs.gtk.org/gtk3/class.Box.html +[hwnd]: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types#HWND +[nsview]: https://developer.apple.com/documentation/appkit/nsview +[surfaceview]: https://developer.android.com/reference/android/view/SurfaceView +[uiview]: https://developer.apple.com/documentation/uikit/uiview + +## How a frame begins + +All frames are born with a call to `RequestFrame` in the [Animator][animator]. + +A frame may be requested for a variety of reasons, ranging from resizing the Flutter view, to lifecycle events like backgrounding or foregrounding an app, to requests from either the app (via dart:ui's [PlatformDispatcher.scheduleFrame][scheduleFrame]) or the embedder (via the [embedder API][embedderAPI]'s `FlutterEngineScheduleFrame`). + +Flutter does some minimal housekeeping when a frame is requested, primarily to ignore any duplicate requests to schedule a frame before the frame is actually produced. + +Once a frame is scheduled, Flutter [waits for a vsync][vsyncWaiter] from the operating system to proceed. + + +## Building the frame + +At the heart of Flutter's graphics workflow is the frame [pipeline][pipeline]. The pipeline is responsible for coordinating work between the UI thread, where the application code runs, and the Raster thread, where rasterization and compositing is performed. See the [threading section][engineArchThreading] of the Engine Architecture wiki for more details on threading in the engine. + +When a vsync occurs, Flutter begins the work of producing the frame in [Animator][animator]'s aptly-named `BeginFrame`. At this point, the animator reserves a spot in the pipeline and notifies the framework to begin the process of producing a frame by triggering the [PlatformDispatcher.onBeginFrame][onBeginFrame] dart:ui callback. + +When using the engine with the Flutter framework, `onBeginFrame` is handled by [handleBeginFrame][handleBeginFrame] in the framework, whose job it is to kick off the production of a [Scene][scene] in the framework. A good overview of this process can be found in the documentation of [RendererBinding.drawFrame][drawFrame] and the [Flutter's Rendering Pipeline][renderingPipelineTalk] tech talk. This process ultimately culminates in the production of a `Scene` which is handed back to the engine through a call to [FlutterView.render][flutterViewRender]. + +On the engine side, a `Scene` is represented as a [LayerTree][layerTree]. Calling `FlutterView.render` hands the layer tree to the Animator via a call its `Render` method, which posts the layer tree to the pipeline and notifies the Rasterizer that it's time to start rasterizing the frame. + +## Rasterizing the frame + +Rasterization is the process of converting the in-memory layer tree into pixels on a surface. Rasterization-related code in Flutter is executed on the Raster thread, which coordinates with the GPU. On some platforms, the Raster thread and the Platform thread may be the same thread. + +Rasterization starts with a call to the `Draw` method in the [Rasterizer][rasterizer]. At this point, the recently-produced `LayerTree` is pulled from the pipeline. The rasterizer does a quick check to see whether the app is running in headless mode (e.g. backgrounded) and if so, the frame is discarded; otherwise, rasterization proceeds. + +Rasterization begins with a request for a surface to which the GPU can draw via a call to the `AcquireFrame` method of [Surface][surface]. This delegates platform-specific code implemented in each embedder in response to callbacks configured in `FlutterRendererConfig` which acquires an appropriate Metal, OpenGL, Vulkan, or software surface for use by the rasterizer. + +Once a surface is acquired, the [LayerTree][layerTree] is rasterized to the surface via recursive `Preroll` and `Paint` calls through the layers. Behavior of these calls is specific to each layer type, but in the end, generally resolves to drawing via either either Skia or Impeller. Once the layer tree has been walked and all graphics operations have been collected, the frame is submitted to the GPU, and embedders are provided a callback to perform further platform-specific handling on their part -- typically presenting the surface via the platform-specific view implementation. + +The above process is repeated until the pipeline is empty. + +## Cleaning up frame resources + +TODO(cbracken): write this up using [this patch](https://github.com/flutter/engine/pull/38038) as a reminder. + +[animator]: https://github.com/flutter/engine/blob/main/shell/common/animator.h +[drawFrame]: https://api.flutter.dev/flutter/rendering/RendererBinding/drawFrame.html +[embedderAPI]: https://github.com/flutter/engine/blob/main/shell/platform/embedder/embedder.h +[engineArchThreading]: ../about/The-Engine-architecture.md#threading +[flutterViewRender]: https://api.flutter.dev/flutter/dart-ui/FlutterView/render.html +[handleBeginFrame]: https://api.flutter.dev/flutter/scheduler/SchedulerBinding/handleBeginFrame.html +[layerTree]: https://github.com/flutter/engine/blob/main/flow/layers/layer_tree.h +[onBeginFrame]: https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/onBeginFrame.html +[pipeline]: https://github.com/flutter/engine/blob/main/shell/common/pipeline.h +[rasterizer]: https://github.com/flutter/engine/blob/main/shell/common/rasterizer.h +[renderingPipelineTalk]: https://www.youtube.com/watch?v=UUfXWzp0-DU +[scene]: https://api.flutter.dev/flutter/dart-ui/Scene-class.html +[surface]: https://github.com/flutter/engine/blob/main/flow/surface.h +[scheduleFrame]: https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/scheduleFrame.html +[vsyncWaiter]: https://github.com/flutter/engine/blob/main/shell/common/vsync_waiter.h diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000000..5bfd804770cc7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,32 @@ +This is an index of team-facing documentation for the [flutter/engine repository](https://github.com/flutter/engine/). + +- [Accessibility on Windows](../platforms/desktop/windows/Accessibility-on-Windows.md) +- [Code signing metadata](./release/Code-signing-metadata.md) for engine binaries +- [Compiling the engine](./contributing/Compiling-the-engine.md) +- [Comparing AOT Snapshot Sizes](./benchmarks/Comparing-AOT-Snapshot-Sizes.md) +- [Crashes](./Crashes.md) +- [Custom Flutter engine embedders](./Custom-Flutter-Engine-Embedders.md) +- [Custom Flutter Engine Embedding in AOT Mode](./Custom-Flutter-Engine-Embedding-in-AOT-Mode.md) +- [Debugging the engine](./Debugging-the-engine.md) +- [Flutter engine operation in AOT Mode](./Flutter-engine-operation-in-AOT-Mode.md) +- [Flutter Test Fonts](../contributing/testing/Flutter-Test-Fonts.md) +- [Flutter's modes](./Flutter's-modes.md) +- [Engine Clang Tidy Linter](./ci/Engine-Clang-Tidy-Linter.md) +- [Engine disk footprint](./Engine-disk-footprint.md) +- [Engine-specific Service Protocol extensions](./Engine-specific-Service-Protocol-extensions.md) +- [Engine pre‐submits and post‐submits](./ci/Engine-pre-submits-and-post-submits.md) +- [Image Codecs in the Flutter Engine](Image-Codecs-in-the-Flutter-Engine.md) +- [Impeller](./impeller/README.md) documentation index +- [Life of a Flutter Frame](Life-of-a-Flutter-Frame.md) +- [Reduce Flutter engine size with MLGO](Reduce-Flutter-engine-size-with-MLGO.md) +- [Resolving common build failures](../platforms/android/Resolving-common-build-failures.md) +- [Setting up the Engine development environment](./contributing/Setting-up-the-Engine-development-environment.md) +- [Supporting legacy platforms](Supporting-legacy-platforms.md) +- [Testing Android Changes in the Devicelab on an Emulator](../platforms/android/Testing-Android-Changes-in-the-Devicelab-on-an-Emulator.md) +- [Testing the engine](./testing/Testing-the-engine.md) +- [Testing presubmit Engine PRs with the Flutter framework](Testing-presubmit-Engine-PRs-with-the-Flutter-framework.md) +- [The Engine architecture](../about/The-Engine-architecture.md) +- [Upgrading Engine's Android API version](../platforms/android/Upgrading-Engine's-Android-API-version.md) +- [Using the Dart Development Service (DDS) and Flutter DevTools with a custom Flutter Engine Embedding](./Using-the-Dart-Development-Service-(DDS)-and-Flutter-DevTools-with-a-custom-Flutter-Engine-Embedding.md) +- [Using Sanitizers with the Flutter Engine](./Using-Sanitizers-with-the-Flutter-Engine.md) +- [Why we have a separate engine repo](../about/Why-we-have-a-separate-engine-repo.md) diff --git a/docs/Reduce-Flutter-engine-size-with-MLGO.md b/docs/Reduce-Flutter-engine-size-with-MLGO.md new file mode 100644 index 0000000000000..75ed9b2c02e6e --- /dev/null +++ b/docs/Reduce-Flutter-engine-size-with-MLGO.md @@ -0,0 +1,233 @@ +Mobile apps are very sensitive to their download sizes as every increase in KB +may result in a user number decrease. Flutter engine (`libflutter.so`) has to be +included in every Flutter app and it has a size of several MBs. So we'll try to +reduce its size by using [MLGO][MLGO]. It's different from the previous Flutter +attempt of reducing sizes as MLGO does not require any code or dependency +removals. + +Reducing engine size with MLGO needs to 1) train a model once, 2) apply that +model to compile the Flutter engine. Note that model training does not need to +happen too frequently - the model should 'hold up' to code changes over +weeks/months. On Ubuntu, do the following: + +- **Follow the [Setting-up-the-Engine-development-environment][engine setup]**. + To check if this step is successful, try [compiling for Android][compile + android]. For size comparisons, we recommend using the release Android build + `./flutter/tools/gn --android --runtime-mode=release --no-goma`. (Option + `--no-goma` is needed if you're not a Googler, or if you're using a custom + Clang as we'll do later with MLGO.) +- **Set up [MLGO] LLVM**. (The steps are adapted from [MLGO demo][MLGO demo].) + 1. Prerequisites: `sudo apt-get install cmake ninja-build lld`. + 2. Create a root directory for everything MLGO related `mkdir ~/mlgo && + export MLGO_DIR=~/mlgo` + 3. Clone MLGO repo + `cd $MLGO_DIR && git clone https://github.com/google/ml-compiler-opt.git` + 4. Tensorflow dependencies + ```bash + cd $MLGO_DIR + sudo apt-get install python3-pip + python3 -m pip install --upgrade pip + python3 -m pip install --user -r ml-compiler-opt/requirements.txt + + TF_PIP=$(python3 -m pip show tensorflow | grep Location | cut -d ' ' -f 2) + + export TENSORFLOW_AOT_PATH="${TF_PIP}/tensorflow" + + mkdir $MLGO_DIR/tensorflow + export TENSORFLOW_C_LIB_PATH=$MLGO_DIR/tensorflow + + wget --quiet https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-linux-x86_64-1.15.0.tar.gz + + tar xfz libtensorflow-cpu-linux-x86_64-1.15.0.tar.gz -C "${TENSORFLOW_C_LIB_PATH}" + ``` + 5. Clone llvm-project + ```bash + cd $MLGO_DIR && git clone https://github.com/llvm/llvm-project.git + export LLVM_SRCDIR=$MLGO_DIR/llvm-project + export LLVM_INSTALLDIR=$MLGO_DIR/llvm-install + ``` + 6. Build LLVM + ```bash + cd ${LLVM_SRCDIR} + mkdir build + cd build + cmake -G Ninja \ + -DLLVM_ENABLE_LTO=OFF \ + -DCMAKE_INSTALL_PREFIX= \ + -DTENSORFLOW_C_LIB_PATH=${TENSORFLOW_C_LIB_PATH} \ + -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=On \ + -C ${LLVM_SRCDIR}/clang/cmake/caches/Fuchsia-stage2.cmake \ + ${LLVM_SRCDIR}/llvm + + ninja distribution + DESTDIR=${LLVM_INSTALLDIR} ninja install-distribution-stripped + ``` +- **Build Flutter engine for MLGO training** + ```bash + # Set your engine dir appropriately if it's not in the default location + export ENGINE_DIR=~/flutter/engine/src + cd $ENGINE_DIR + + sed -i \ + 's/cflags += lto_flags/cflags += lto_flags + ["-Xclang", "-fembed-bitcode=all"]/' \ + build/config/compiler/BUILD.gn + + sed -i \ + "s/prefix = rebase_path(\"\/\/buildtools\/\$host_dir\/clang\/bin\", root_build_dir)/prefix = \"${LLVM_INSTALLDIR//\//\\/}\/bin\"/" \ + build/toolchain/android/BUILD.gn + + ./flutter/tools/gn --android --runtime-mode=release --no-goma --no-lto + ninja -C out/android_release + ``` +- **Train the model** + ```bash + export CORPUS=$MLGO_DIR/corpus + cd $MLGO_DIR/ml-compiler-opt + python3 compiler_opt/tools/extract_ir.py \ + --cmd_filter="^-Oz$" \ + --input=$ENGINE_DIR/out/compile_commands.json \ + --input_type=json \ + --llvm_objcopy_path=$LLVM_INSTALLDIR/bin/llvm-objcopy \ + --output_dir=$CORPUS + + export DEFAULT_TRACE=$MLGO_DIR/default_trace + export WARMSTART_OUTPUT_DIR=$MLGO_DIR/warmstart + export OUTPUT_DIR=$MLGO_DIR/model + + rm -rf $DEFAULT_TRACE && \ + PYTHONPATH=$PYTHONPATH:. python3 \ + compiler_opt/tools/generate_default_trace.py \ + --data_path=$CORPUS \ + --output_path=$DEFAULT_TRACE \ + --compile_task=inlining \ + --clang_path=$LLVM_INSTALLDIR/bin/clang \ + --llvm_size_path=$LLVM_INSTALLDIR/bin/llvm-size \ + --sampling_rate=0.2 + + rm -rf $WARMSTART_OUTPUT_DIR && \ + PYTHONPATH=$PYTHONPATH:. python3 \ + compiler_opt/rl/train_bc.py \ + --root_dir=$WARMSTART_OUTPUT_DIR \ + --data_path=$DEFAULT_TRACE \ + --gin_files=compiler_opt/rl/inlining/gin_configs/behavioral_cloning_nn_agent.gin + + # The following will take about half a day. + rm -rf $OUTPUT_DIR && \ + PYTHONPATH=$PYTHONPATH:. python3 \ + compiler_opt/rl/train_locally.py \ + --root_dir=$OUTPUT_DIR \ + --data_path=$CORPUS \ + --clang_path=$LLVM_INSTALLDIR/bin/clang \ + --llvm_size_path=$LLVM_INSTALLDIR/bin/llvm-size \ + --num_modules=100 \ + --gin_files=compiler_opt/rl/inlining/gin_configs/ppo_nn_agent.gin \ + --gin_bindings=train_eval.warmstart_policy_dir=\"$WARMSTART_OUTPUT_DIR/saved_policy\" + ``` +- **Build LLVM with the trained model** + ```bash + cd $LLVM_SRCDIR + rm -rf llvm/lib/Analysis/models/inliner/* + cp -rf $OUTPUT_DIR/saved_policy/* llvm/lib/Analysis/models/inliner/ + + mkdir build-release + cd build-release + cmake -G Ninja \ + -DLLVM_ENABLE_LTO=OFF \ + -DCMAKE_INSTALL_PREFIX= \ + -DTENSORFLOW_AOT_PATH=${TENSORFLOW_AOT_PATH} \ + -C ${LLVM_SRCDIR}/clang/cmake/caches/Fuchsia-stage2.cmake \ + ${LLVM_SRCDIR}/llvm + + export LLVM_INSTALLDIR_RELEASE=$LLVM_INSTALLDIR-release + ninja distribution + DESTDIR=${LLVM_INSTALLDIR_RELEASE} ninja install-distribution-stripped + ``` +- **Build Flutter engine using LLVM with the trained model** + ```bash + cd $ENGINE_DIR + git stash # Undo previous changes for model training + + sed -i \ + 's/cflags += lto_flags/cflags += lto_flags + ["-mllvm", "-enable-ml-inliner=release"]/' \ + build/config/compiler/BUILD.gn + + sed -i \ + "s/prefix = rebase_path(\"\/\/buildtools\/\$host_dir\/clang\/bin\", root_build_dir)/prefix = \"${LLVM_INSTALLDIR_RELEASE//\//\\/}\/bin\"/" \ + build/toolchain/android/BUILD.gn + + ./flutter/tools/gn --android --runtime-mode=release --no-goma --no-lto + ninja -C out/android_release libflutter.so + ``` +- **Compare**. To compare the engine size with or without MLGO, one can add or + remove the `["-mllvm", "-enable-ml-inliner=release"]` flags in + `build/config/compiler/BUILD.gn`, compile the engine, and check the size of + `out/android_release/lib.stripped/libflutter.so`. As end-users will download + zipped engine, we also recommend comparing its zipped size. + ```bash + export ENGINE_LIB_DIR=$ENGINE_DIR/out/android_release/lib.stripped + + cd $ENGINE_DIR + ./flutter/tools/gn --android --runtime-mode=release --no-goma --no-lto + ninja -C out/android_release libflutter.so + cd $ENGINE_LIB_DIR + mv libflutter.so libflutter.ml_nolto.so + zip libflutter.ml_nolto.so.zip libflutter.ml_nolto.so + + cd $ENGINE_DIR + ./flutter/tools/gn --android --runtime-mode=release --no-goma + ninja -C out/android_release libflutter.so + cd $ENGINE_LIB_DIR + mv libflutter.so libflutter.ml_lto.so + zip libflutter.ml_lto.so.zip libflutter.ml_lto.so + + # Remove the ML flags to disable ML. + cd $ENGINE_DIR + sed -i \ + 's/cflags += lto_flags + \["-mllvm", "-enable-ml-inliner=release"\]/cflags += lto_flags/' \ + build/config/compiler/BUILD.gn + + cd $ENGINE_DIR + ./flutter/tools/gn --android --runtime-mode=release --no-goma --no-lto + ninja -C out/android_release libflutter.so + cd $ENGINE_LIB_DIR + mv libflutter.so libflutter.noml_nolto.so + zip libflutter.noml_nolto.so.zip libflutter.noml_nolto.so + + cd $ENGINE_DIR + ./flutter/tools/gn --android --runtime-mode=release --no-goma + ninja -C out/android_release libflutter.so + cd $ENGINE_LIB_DIR + mv libflutter.so libflutter.noml_lto.so + zip libflutter.noml_lto.so.zip libflutter.noml_lto.so + + ls -l + ``` + + Here's the table of size comparisons for engine version b9ecd8a. + + | Flutter engine size comparison | ML_LTO | ML_NOLTO | NOML_LTO | NOML_NOLTO | + | --- | --- | --- | --- | --- | + | unzipped size (bytes) | 6270960 | 6338580 | 6312012 | 6577684 | + | zipped size (bytes) | 3586091 | **3577604** | 3606484 | 3689468 | + | unzipped size change over NOML_LTO | -0.65% | 0.4% | 0 | 4.21% | + | zipped size change over NOML_LTO | -0.57% | **-0.80%** | 0 | 2.3% | + | unzipped size change over NOML_NOLTO | -4.66% | -3.64% | -4.04% | 0 | + | zipped size change over NOML_NOLTO | -2.80% | -3.03% | -2.25% | 0 | + +## Conclusion + +As shown in the table above, for the zipped size, the winner here is the +ML_NOLTO version which is even smaller than the ML_LTO version. It has a 0.8% +reduction over our previous art of NOML_LTO. + +The ML_LTO version is not very good because currently the model can only be +trained without LTO. [MLGO][MLGO] is planning to allow ThinLTO in their +training. Hopefully, it will help achieve the MLGO's normal reduction of 3%-5% +(e.g., ML_NOLTO vs NOML_NOLTO) when the training and final build are in the same +condition. + + +[MLGO]: https://github.com/google/ml-compiler-opt +[engine setup]: ./contributing/Setting-up-the-Engine-development-environment +[compile android]: ./contributing/Compiling-the-engine#compiling-for-android-from-macos-or-linux +[MLGO demo]: https://github.com/google/ml-compiler-opt/blob/main/docs/demo/demo.md diff --git a/docs/Supporting-legacy-platforms.md b/docs/Supporting-legacy-platforms.md new file mode 100644 index 0000000000000..632a65613fbba --- /dev/null +++ b/docs/Supporting-legacy-platforms.md @@ -0,0 +1,28 @@ +## Building ARMv7 (iOS) & armeabi v7a (Android) with Xcode10 + +In Xcode10, the i386 architecture is deprecated for macOS, so building the Flutter engine for armv7/armeabi-v7a fails. Specifically, libraries like CoreFoundation contain only code for the x86_64 architecture. + +![iOS ARMv7](https://user-images.githubusercontent.com/817851/45751101-e7a54980-bc43-11e8-833f-b6458c9a4762.png) + +![Android armeabi-v7a](https://user-images.githubusercontent.com/817851/45751099-e70cb300-bc43-11e8-97fa-a877dff5449d.png) + +To address this, get the MacOS 10.13 SDK from Xcode 9.x from [Apple](https://developer.apple.com/download/more/), and extract the SDK components from the `.xip` file. Uncompress the SDK into `/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs` and name the SDK `MacOSX10.13.sdk`: + +![Uncompressed SDK in Xcode10](https://user-images.githubusercontent.com/817851/45752211-47512400-bc47-11e8-88fe-b738ac53831f.png) + +To check if the logic is fine, run command below: + +```bash +python your-flutter-engine-path/engine/src/build/mac/find_sdk.py 10.12 +``` + +When `find_sdk.py` return 10.13, the ninja build will succeed for gen_snapshot (i386), Flutter.framework (ARMv7) and libflutter.so (armeabi-v7a). + +## Build Flutter engine for 32bit iOS simulator on modern Mac(x86_64) + +To build the Flutter engine for iOS simulator on a modern Mac(x86_64), the gn command will generate a `target_cpu` value with x64. Henceforth, the Flutter.framework and gen_snapshot will be x86_64. +However, sometimes you may want to develop Flutter on a 32bit simulator(like iPhone5), you will need both Flutter.framework and gen_snapshot to be i386. + +Follow instruction below to change the default behavior in gn command: +1. Edit your-flutter-engine-path/engine/src/flutter/tools/gn +![Edit gn](https://user-images.githubusercontent.com/817851/49006557-57840300-f1a4-11e8-850a-d019dc854bbd.png) \ No newline at end of file diff --git a/docs/Testing-presubmit-Engine-PRs-with-the-Flutter-framework.md b/docs/Testing-presubmit-Engine-PRs-with-the-Flutter-framework.md new file mode 100644 index 0000000000000..d0961a23885b3 --- /dev/null +++ b/docs/Testing-presubmit-Engine-PRs-with-the-Flutter-framework.md @@ -0,0 +1,48 @@ +# Running Framework presubmit tests on Engine PRs + +This documentation describes how to run flutter/flutter presubmit checks on flutter/engine PRs before submitting them. + +# Overview + +1. Wait for all presubmit checks on your flutter/engine PR to be green. +2. Determine the commit hash for your flutter/engine PR. +3. Create and upload a flutter/flutter PR, (OR run tests locally). +4. Wait for flutter/flutter presubmits/tests to run ☕. + +Step (1) is the usual flutter/engine workflow. + +# 2. The commit hash + +1. Go to the "Commits" tab in the GitHub UI for you Engine PR. +1. Click the button to copy the most recent commit hash to your clipboard. + +Screenshot 2023-08-04 at 12 54 55 PM + +# 3. Create and upload a flutter/flutter PR. + +Edit your flutter/flutter checkout as follows: + +1. `bin/internal/engine.version` should be edited to contain the commit hash from (2). +1. `bin/internal/engine.realm` should be edited to contain the string `flutter_archives_v2`. + +To run flutter/flutter presubmits on CI, you can accomplish these two edits directly in the GitHub editor UI, if desired. Otherwise, upload a flutter/flutter PR with these changes. + +You can also build apps, and run tests locally at this point. + +# 4. Wait for flutter/flutter presubmits to run ☕. + +The flutter/flutter presubmit checks will run. There will be at least two failures: +1. A Flutter CLI test will ensure that a PR with a non-empty `engine.realm` file will fail a presubmit check. +1. The `fuchsia_precache` test will fail because Fuchsia artifacts are not uploaded from Engine presubmit runs. + +Any other failures are possibly due to the changes to flutter/engine, so deflake and examine them carefully. + +# 5. Devicelab tests + +A subset of devicelab tests are available for optionally running in presubmit on flutter/flutter PRs. They are the tests listed in the flutter/flutter [.ci.yaml](https://github.com/flutter/flutter/blob/main/.ci.yaml) file that are prefixed with `Linux_android`, `Mac_android`, and `Mac_ios`. + +To run one of these tests, remove the line `presubmit: false` from the `.ci.yaml` file under the test you'd like to run. For an example, see the PR [here](https://github.com/flutter/flutter/pull/135254). + +Screenshot 2023-09-21 at 3 19 51 PM + +This will trigger the devicelab test to run. The test will show up in the list of presubmit checks, and you can click through to the [LUCI page](https://ci.chromium.org/ui/p/flutter/builders/try/Linux_android%20new_gallery__transition_perf/2/overview) to see the results. diff --git a/docs/Using-Sanitizers-with-the-Flutter-Engine.md b/docs/Using-Sanitizers-with-the-Flutter-Engine.md new file mode 100644 index 0000000000000..9540d12d803c9 --- /dev/null +++ b/docs/Using-Sanitizers-with-the-Flutter-Engine.md @@ -0,0 +1,125 @@ + +All Flutter Engine builds can now enable a combination of the following sanitizers. The different sanitizers are used to isolate specific classes of construction issues. + +* **Thread Sanitizer**: Detects data races. +* **Address Sanitizer**: Detects memory errors like use-after-free, buffer overflows... +* **Memory Sanitizer**: Detects reads on uninitialized memory. +* **Undefined Behavior Sanitizer**: Detects undefined behavior. +* **Leak Sanitizer**: Detects memory leaks. + +While the buildroot is wired up to attempt sanitizer enabled builds for all targets, not all target architectures, host platform and sanitizer combinations are supported. Support for each sanitizer also varies greatly with each toolchain version. For this reason, and due to general constraints in available build/test infrastructure, these sanitizers are not enabled by default on presubmits or build-bots. It is best to work backwards from a problem and choose a sanitizer that has the best shot of isolating the same. + + +## General Usage Guidelines + +Most sanitizer enabled variants will either fail to build at all or fail when running specific unit-test targets. These failures are either because there are false positives that have not been annotated correctly or genuine issues in either the Flutter Engine or Dart VM. However, it is possible to discover further issues without fixing them all. This is done by selectively suppressing known issues. The suppressions and other sanitizer options have to be specified as environment options. These options can be specified in one shot by invoking the following in the current shell: + + +``` +source ./flutter/testing/sanitizer_suppressions.sh +``` + + +This should enable relevant options for all known sanitizers and also print the files containing suppressions for each sanitizer. + +Sample output: + + +``` +Using Thread Sanitizer suppressions in ./flutter/testing/tsan_suppressions.txt +Using Leak Sanitizer suppressions in ./flutter/testing/lsan_suppressions.txt +``` + + +You can run the specific unit-test binaries in the terminal and all sanitizer options and suppressions will take hold. + +If an issue is raised that is not previously known, a suppression may be added and a bug filed to track the same. Instructions on how to add suppressions for the specific sanitizer are specific at the top of the relevant suppressions file. + +Make sure to add suppression that are as detailed as possible. Adding suppressions that are too broad may suppress errors from issues that are actually new and untracked. If you find that the issue you expect is not caught by the sanitizer, make sure to check the list of suppressions to see if any of the suppressed issues look relevant. If so, you might need to selectively disable suppressions: + + +``` +----------------------------------------------------- +Suppressions used: + count bytes template + 1 120 class_createInstance + 5 80 MakeSkSurfaceFromBackingStore + 3 128 _dispatch_once_callout +----------------------------------------------------- +``` + + +Support for sanitizer enabled builds using Goma is spotty. Disable Goma for more reliable builds till these issues are addressed. + +All sanitizer caught issues are tagged with the [sanitizer](https://github.com/flutter/flutter/labels/sanitizer) label. + + +## Leak Sanitizer + +A tool used to detect memory leaks. Official documentation is at [https://clang.llvm.org/docs/LeakSanitizer.html](https://clang.llvm.org/docs/LeakSanitizer.html). Enable using the `--lsan` GN flag on any target. For best results, use this with unoptimized build variants. The buildroot is configured to use the ideal arguments in this mode. Full documentation on how to add suppressions to this file is at [https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions). This tool can be used either in standalone mode or in conjunction with Address Sanitizer. + + +``` +$ ./flutter/tools/gn --runtime-mode debug --lsan --unoptimized --no-goma +$ autoninja -C out/host_debug_unopt +$ source ./flutter/testing/sanitizer_suppressions.sh +$ ./out/host_debug_unopt/embedder_unittests +``` + + +## Address Sanitizer + +Address sanitizer detects memory errors. Official documentation is at [https://github.com/google/sanitizers/wiki/AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer). Enable using the `--asan` flag. Enabling address sanitizer also implicitly enables +Leak Sanitizer. The `./flutter/testing/sanitizer_suppressions.sh` script enables leak sanitization in Address Sanitizer builds. + + +``` +$ ./flutter/tools/gn --runtime-mode debug --asan --unoptimized --no-goma +$ autoninja -C out/host_debug_unopt +$ source ./flutter/testing/sanitizer_suppressions.sh +$ ./out/host_debug_unopt/embedder_unittests +``` + + +Address sanitizer has [spotty support on aarch64](https://github.com/google/sanitizers/wiki/AddressSanitizer#introduction) targets. Use it on x64 target for best results. + + +## Undefined Behavior Sanitizer + +Catches undefined behavior. Official documentation at [https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html). Enable using the `--ubsan` flag. The `sanitizer_suppressions.sh` file will specify a suppressions files. [Classes of errors](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#id4) can be disabled at runtime. + + +``` +$ ./flutter/tools/gn --runtime-mode debug --ubsan --unoptimized --no-goma +$ autoninja -C out/host_debug_unopt +$ source ./flutter/testing/sanitizer_suppressions.sh +$ ./out/host_debug_unopt/embedder_unittests +``` + + + +## Thread Sanitizer + +Catches data races. Official documentation at [https://clang.llvm.org/docs/ThreadSanitizer.html](https://clang.llvm.org/docs/ThreadSanitizer.html). + + +``` +$ ./flutter/tools/gn --runtime-mode debug --tsan --unoptimized --no-goma +$ autoninja -C out/host_debug_unopt +$ source ./flutter/testing/sanitizer_suppressions.sh +$ ./out/host_debug_unopt/embedder_unittests +``` + + + +## Memory Sanitizer + +Detects reads of uninitialized memory. This sanitizer is only available on Linux. Enable using the `--msan` flag. + + +``` +$ ./flutter/tools/gn --runtime-mode debug --msan --unoptimized --no-goma +$ autoninja -C out/host_debug_unopt +$ source ./flutter/testing/sanitizer_suppressions.sh +$ ./out/host_debug_unopt/embedder_unittests +``` diff --git a/docs/Using-the-Dart-Development-Service-(DDS)-and-Flutter-DevTools-with-a-custom-Flutter-Engine-Embedding.md b/docs/Using-the-Dart-Development-Service-(DDS)-and-Flutter-DevTools-with-a-custom-Flutter-Engine-Embedding.md new file mode 100644 index 0000000000000..1f6177c521b18 --- /dev/null +++ b/docs/Using-the-Dart-Development-Service-(DDS)-and-Flutter-DevTools-with-a-custom-Flutter-Engine-Embedding.md @@ -0,0 +1,61 @@ +When attempting to connect to the VM service URI output by the Flutter engine in the context of a custom embedder, users may encounter the following error: + +`This VM does not have a registered Dart Development Service (DDS) instance and is not currently serving Dart DevTools.` + +This happens when a Flutter application is launched without using the `flutter` CLI tool, which typically is responsible for starting a Dart Development Service (DDS) instance. DDS is middleware for the Dart VM Service that provides additional functionality like log and event history, and can be configured to serve the DevTools developer tooling suite. + +Developers working on custom embeddings of the Flutter engine can start a DDS instance in one of two ways: + +1) Using the `dart development-service` command shipped with the Dart SDK (**recommended**). +2) Starting a Flutter DevTools instance using the `dart devtools` shipped with the Dart SDK, providing the VM service URI as an argument (e.g., `dart devtools http://localhost:8181`). + +## Using `dart development-service` + +DDS can be started using the `dart development-service` command. As of writing, the command has the following interface allowing for configuration of the service: + +``` +Start Dart's development service. + +Usage: dart [vm-options] development-service [arguments] +-h, --help Print this usage information. + --vm-service-uri= (mandatory) The VM service URI DDS will connect to. + --bind-address=
The address DDS should bind to. + (defaults to "localhost") + --bind-port= The port DDS should be served on. + (defaults to "0") + --[no-]disable-service-auth-codes Disables authentication codes. + --[no-]serve-devtools If provided, DDS will serve DevTools. If not specified, "--devtools-server-address" is ignored. + --devtools-server-address Redirect to an existing DevTools server. Ignored if "--serve-devtools" is not specified. + --[no-]enable-service-port-fallback Bind to a random port if DDS fails to bind to the provided port. + --cached-user-tags A set of UserTag names used to determine which CPU samples are cached by DDS. + --google3-workspace-root Sets the Google3 workspace root used for google3:// URI resolution. + +Run "dart help" to see global options. +``` + +The `--vm-service-uri` option is required and specifies the URI of the Dart VM service served by the Flutter engine. If provided, the `--serve-devtools` flag will result in the DevTools instance shipped with the Dart SDK from DDS's HTTP server. + +Running the command will result in JSON encoded connection information being output to `stdout`: + +```bash +$ dart development-service --vm-service-uri=http://127.0.0.1:59113/BBPoXnZUWFU=/ --serve-devtools +{"state":"started","ddsUri":"http://127.0.0.1:59123/tbrR0DzW2j8=/","devToolsUri":"http://127.0.0.1:59123/tbrR0DzW2j8=/devtools?uri=ws://127.0.0.1:59123/tbrR0DzW2j8=/ws","dtd":{"uri":"ws://127.0.0.1:59122/R1LbdlhtkUygRWNA"}} +``` + +Once DDS has started, all VM service requests should be made through the URI provided by DDS instead of the original VM service URI. In the context of the standalone Dart VM (i.e., `dart`) and the `flutter` tool, the original VM service URI is hidden and the DDS URI is advertised as the Dart VM service URI to reduce the likelihood of developers accidentally connecting to the VM service directly. Direct connections to a VM service with an active DDS instance attached will be rejected. + +The DDS instance will automatically shutdown when the target application is closed, requiring no manual lifecycle management. + +## Using `dart devtools` + +Developers are also able to start DevTools using the `dart devtools` command. By providing the VM service URI as a positional parameter, the served DevTools instance will automatically connect to the provided target application. However, before connecting directly to the VM service URI, the command first checks that the provided VM service URI points to a DDS instance. If it doesn't, the command will start DDS, print the DDS URI to console, and then launch a DevTools instance that connects to the DDS instance directly instead of to the provided VM service URI. + +```bash +$ dart devtools http://127.0.0.1:59251/2LS6f3Kb2JI=/ +Started the Dart Development Service (DDS) at http://127.0.0.1:59260/38XeuQpIHRE=/ +Serving DevTools at http://127.0.0.1:9101. + + Hit ctrl-c to terminate the server. +``` + +As with the `dart development-service` command, the lifecycle of DDS is tied directly to the lifecycle of the application it's connected to. However, using the `dart devtools` command does not cause DevTools to be served by DDS, meaning that DevTools will not be available if the `dart devtools` process is killed, even though DDS will remain attached to the target application. \ No newline at end of file diff --git a/docs/benchmarks/Comparing-AOT-Snapshot-Sizes.md b/docs/benchmarks/Comparing-AOT-Snapshot-Sizes.md new file mode 100644 index 0000000000000..c397f41fe7ee0 --- /dev/null +++ b/docs/benchmarks/Comparing-AOT-Snapshot-Sizes.md @@ -0,0 +1,90 @@ +These instructions can be used to prepare a tabulated summary of the differences in the sizes of two AOT snapshots. The instructions assume that the Flutter Engine has been [setup](../contributing/Setting-up-the-Engine-development-environment.md) on the host (at `FLUTTER_ENGINE` in these instructions). + +Build the AOT snapshot (`flutter build aot`) for the application but pass in the `--verbose` flag. We need to find the `gen_snapshot` invocation and re-run it with an extra option (`--print-instructions-sizes-to`). If you are instrumenting with a local engine, the `flutter build` [takes a `--local-engine` and `--local-engine-host` flag](../Debugging-the-engine.md#running-a-flutter-app-with-a-local-engine) as well. + +Here is an example of the updated invocation. Specify the path to a JSON file that acts as a summary (`SUMMARY_LOCATION` in these instructions) as follows. + +```bash +$FLUTTER_ENGINE/out/host_debug_unopt/gen_snapshot \ + --print-instructions-sizes-to=$SUMMARY_LOCATION \ + --causal_async_stacks \ + --packages=.packages \ + --deterministic \ + --snapshot_kind=app-aot-blobs \ + --vm_snapshot_data=build/aot/vm_snapshot_data \ + --isolate_snapshot_data=build/aot/isolate_snapshot_data \ + --vm_snapshot_instructions=build/aot/vm_snapshot_instr \ + --isolate_snapshot_instructions=build/aot/isolate_snapshot_instr \ + build/aot/app.dill +``` + +Save the file at `SUMMARY_LOCATION` as `before.json` + +Now, either change the Dart code with the changes you wish to see the effects, or, rebuild the engine to create an updated `gen_snapshot` binary. + +After you have made necessary changes, re-run `flutter build aot` again. This step is important because AOT compilation has a [kernel compilation step](../Custom-Flutter-Engine-Embedding-in-AOT-Mode.md#generating-the-kernel-snapshot) before the `gen_snapshot` invocation. + +Re-run the gen_snapshot invocation and save the resulting file to `after.json`. + +Run the `compare_size.dart` tool and pass in the `before.json` and `after.json` files to generate the summary. + +An example invocation looks as follow. + +``` +$FLUTTER_ENGINE/out/host_debug_unopt/dart-sdk/bin/dart \ + before.json \ + after.json +``` + +This should dump something like the following to the console. + +``` ++------------+----------------------------------------------------------+--------------+ +| Library | Method | Diff (Bytes) | ++------------+----------------------------------------------------------+--------------+ +| dart:async | new ZoneSpecification.from | +2136 | +| dart:async | runZoned | +1488 | +| dart:async | new _CustomZone | +927 | +| dart:async | runZoned. | +881 | +| dart:async | _rootFork | +504 | +| dart:async | _rootCreatePeriodicTimer | +500 | +| dart:async | _rootCreateTimer | +498 | +| dart:async | _rootRegisterUnaryCallback | +485 | +| dart:async | _rootRegisterBinaryCallback | +485 | +| dart:async | _rootRegisterCallback | +485 | +| dart:async | _rootPrint | +453 | +| dart:async | _CustomZone.fork | +396 | +| dart:async | _rootErrorCallback | +389 | +| dart:async | _CustomZone.bindUnaryCallbackGuarded | +368 | +| dart:async | _rootHandleUncaughtError | +342 | +| dart:async | _CustomZone.runBinary | +296 | +| dart:async | _CustomZone.runUnary | +293 | +| dart:async | _CustomZone.[] | +291 | +| dart:async | _CustomZone.registerCallback | +290 | +| dart:async | _CustomZone.run | +290 | +| dart:async | _CustomZone.registerUnaryCallback | +290 | +| dart:async | _CustomZone.registerBinaryCallback | +290 | +| dart:async | _CustomZone.runBinaryGuarded | +289 | +| dart:async | _CustomZone.runUnaryGuarded | +286 | +| dart:async | _RootZone.fork | +283 | +| dart:async | _CustomZone.bindCallback | +259 | +| dart:async | _CustomZone.bindUnaryCallback | +259 | +| dart:async | _CustomZone.bindUnaryCallback. | +248 | +| dart:async | _RootZone.bindUnaryCallback. | +248 | +| dart:async | _CustomZone.bindUnaryCallbackGuarded. | +248 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +| | [Stub] Type Test Type: class 'PopupMenuEntry' | -128 | +| | [Stub] Type Test Type: class '_SyncIterator@0150898' | -128 | +| | [Stub] Type Test Type: class 'PopupMenuItem' | -128 | +| | [Stub] Type Test Type: class 'FormFieldState' | -128 | +| | [Stub] Type Test Type: class 'PopupMenuButton' | -128 | +| | [Stub] Type Test Type: class '_SyncIterator@0150898' | -131 | +| | [Stub] Type Test Type: class '_SplayTreeMapNode@3220832' | -139 | +| | [Stub] Type Test Type: class '_SplayTreeMapNode@3220832' | -165 | +| dart:io | new Directory | -211 | +| dart:io | new Link | -211 | ++------------+----------------------------------------------------------+--------------+ +Total change +24036 bytes. + +``` diff --git a/docs/ci/Engine-Clang-Tidy-Linter.md b/docs/ci/Engine-Clang-Tidy-Linter.md new file mode 100644 index 0000000000000..05879f82181e6 --- /dev/null +++ b/docs/ci/Engine-Clang-Tidy-Linter.md @@ -0,0 +1,56 @@ +# Engine Clang Tidy Linter + +## Description + +In May 2020, [`clang-tidy`](https://clang.llvm.org/extra/clang-tidy/) was added as a CI step to the Flutter Engine. Previously the only lint checks that were happening in the engine were formatting, there were no semantic checks. Now there are, but that means there is work to be done migrating all the code to conform to all the lint checks. + +If a file has `// FLUTTER_NOLINT` at the top, it has issues with the lint that haven't been addressed and the linter will ignore it. As the issues are fixed the comments should be removed. + +You can run the linter locally by running `flutter/ci/lint.sh`. + +## CI background information + +* The clang-tidy ci step is run 4 times: host_debug on mac, ios_debug on mac, host_debug on linux, android_debug_arm64 on linux. +* Before the linter can run, the target must be built in order to generate code. +* Clang-tidy jobs are sharded such that the intersection of files in iOS and macOS are shared, similarly for Linux and Android. + +## FAQs + +### I don't understand this lint error, where do I get help? + +You can ask on the `hackers-engine` discord channel. Ping @gaaclarke or @zanderso if you don't get the response you want. + +### Hey, why are/aren't you checking for X? + +The checks that are enabled are negotiable. If you think we are missing something, please discuss it on `hacker-engine`. + +### Can I just use `NOLINT` to turn off the error? + +You can, but please get explicit approval to do from someone on the team. + +### How do I turn on a large new lint? + +Here are things that can make it easier to land large new lints. + +#### Tips + +* Try to reduce the number of checks you are turning on at a time, they can have cascading effects where fixing one check with "clang-tidy fix" can cause violations with other checks. +* Prefer using NOLINTNEXTLINE over NOLINT since auto formatting can move NOLINT comments and break them. + +#### Clang-tidy fix on CI + +Instead of running clang-tidy fix locally on your machines 4 times you can get the CI bots to print out the fix. Here's steps on how to do that: + +1. Edit `//ci/clang_tidy.sh`: + ```diff + # To run on CI, just uncomment the following line: + -# FLUTTER_LINT_PRINT_FIX=1 + +FLUTTER_LINT_PRINT_FIX=1 + ``` + This will run on _all_ files, and print out the patch generated by `clang-tidy fix` in the CI bots. + +2. Make a draft PR with the check added and FLUTTER_LINT_PRINT_FIX=1 +3. Look at the output of failed clang-tidy runs and make sure that it didn't garble the fix. Sometimes that happens and if it does, you'll have to manually fix where it garbled the fix or use NOLINTNEXTLINE. +4. Copy the patch the CI bot printed out to the clipboard, in the terminal, at the engine repo, use `git apply`, paste the patch, press ctrl+d then enter. Watch out that there can be overlapping patches between the mac runs and the linux runs since we don't shard across platforms. +5. Commit and push that. +6. When the 4 CI runs are green, remove FLUTTER_LINT_PRINT_FIX=1 and put up for review diff --git a/docs/ci/Engine-pre-submits-and-post-submits.md b/docs/ci/Engine-pre-submits-and-post-submits.md new file mode 100644 index 0000000000000..d137d97d616ba --- /dev/null +++ b/docs/ci/Engine-pre-submits-and-post-submits.md @@ -0,0 +1,79 @@ +The Flutter engine repo runs both pre-submit (before merging) and post-submit (after merging) suites of tests and checks, defined in [`.ci.yaml`](https://github.com/flutter/engine/blob/main/.ci.yaml). + +> [!TIP] +> See [Cocoon Scheduler](https://github.com/flutter/cocoon/blob/main/CI_YAML.md) for details. + +Failure to run appropriate tests for changes can (and do) result in the engine tree turning red, which in turn causes an expensive cascade of developers being blocked, investigative work, reverts, and roll-forwards. Where possible, all attempts should be made to run any/all tests _before_ merging a PR. See nuances (below) for exceptional cases. + + + +* [Pre-submit](#pre-submit) +* [Post-submit](#post-submit) + * [Running post-submits eagerly](#running-post-submits-eagerly) + +## Pre-submit + +Presubmits run (and are required to be passing) to merge a PR: + +Checks + +

+ +For example, the `linux_host_engine` target above runs based on the configuration in [`ci/builders/linux_host_engine.json`](https://github.com/flutter/engine/blob/458956228dad9837956aeb78b2988879e764a0b2/ci/builders/linux_host_engine.json). + +### Nuances + +Typically, pre-submits _always_ run on every PR, and don't need any special attention (other than keeping them green). There are two exceptions: + +1. Targets that provide a `runIf: ...` configuration +2. Changes that impact Clang Tidy + +> [!WARNING] +> +> `runIf: ...` is a powerful (but dangerous) feature that trades predictability for speed. +> +> `runIf` will skip certain targets if a particular file (or commonly, sets of files) are not changed in a given PR. +> +> For example, the [`linux_clang_tidy_presubmit`](https://github.com/flutter/engine/blob/991676f3bc9482eaaeb3764b6b835f0e3ff8b3c5/.ci.yaml#L219-L235) target will not run if only markdown (`*.md`) files are changed. + +Clang Tidy, on the other hand, is only run on _files that have changed in a given PR_. For example, if you have: + +```h +// impeller/a.h +struct A {} +``` + +... files that import that header, such as `impeller/foo/bar/baz.cc`, will _not_ be run in pre-submit. This means that changing (or updating the `DEPS` of libraries that provide) headers is _not_ a safe change, and will _not_ be detected in pre-submit. As an example, [#48705](https://github.com/flutter/engine/pull/48705) had to be reverted (despite passing all pre-submit checks), because the Clang Tidy _post-submit_ caught a failure. + +See [post-submit](#post-submit) below for options to run post-submits eagerly (i.e. as a pre-submit). + +## Post-submit + +Some (albeit fewer) targets are configured with the property `presubmit: false`: + +```yaml + - name: Mac mac_clang_tidy + recipe: engine_v2/engine_v2 + presubmit: false +``` + +These targets will _not_ show up during a PR, and will not be executed, but can (and do) turn the tree red. + +### Running post-submits eagerly + +We've intentionally chosen to make it _easier_ to land PRs, at the cost of turning the tree red periodically because post-submit checks catch something that the developer did not intend (or even know about). As a code author (or reviewer), you can optionally turn on post-submits to run eagerly (during pre-submit) by adding the label `test: all` (available only in the `flutter/engine` repo). + +Add the label, and push the PR (or a new commit, **the scheduler will not understand the label being added without a commit**): + +Screenshot 2023-12-07 at 1 55 48 PM + +

+ +For example, [#48158](https://github.com/flutter/engine/pull/48158) ran _all_ of the checks, including what is typically post-submits: + +Screenshot 2023-12-07 at 1 55 39 PM + +

+ +> [!WARNING] +> This increases the use of workers/capacity, and should be discouraged to be used on _all_ PRs. diff --git a/docs/contributing/Compiling-the-engine.md b/docs/contributing/Compiling-the-engine.md new file mode 100644 index 0000000000000..f209d34afad93 --- /dev/null +++ b/docs/contributing/Compiling-the-engine.md @@ -0,0 +1,330 @@ +_If you've never built the engine before, first see [Setting up the Engine development environment](Setting-up-the-Engine-development-environment.md)._ + +# Contents + +Depending on the platform you are making changes for, you may be interested in all or only some of the sections below: + +* [General Compilation Tips](#general-compilation-tips) +* [Using a custom Dart SDK](#using-a-custom-dart-sdk) +* [Compiling for Android](#compiling-for-android-from-macos-or-linux) +* [Compiling for iOS (from macOS)](#compiling-for-ios-from-macos) +* [Compiling for macOS or Linux](#compiling-for-macos-or-linux) +* [Compiling for Windows](#compiling-for-windows) +* [Compiling for Fuchsia](#compiling-for-fuchsia) +* [Compiling for the Web](#compiling-for-the-web) +* [Compiling for testing](#compiling-for-testing) + +## General Compilation Tips + +- For local development and testing, it's generally preferable to use `--unopt` builds. + These builds will have additional logging and checks enabled, and generally use build + and link flags that lead to faster compilation and better debugging symbols. + If you are trying to do performance testing with a local build, do not use the `--unopt` + flag. +- Link Time Optimization: Optimized builds also perform Link Time Optimization of all + binaries. This makes the linker take a lot of time and memory to produce binaries. If + you need optimized binaries but don't want to perform LTO, add the `--no-lto` flag. +- Android and iOS expect both a `host` and `android` (or `ios`) build. It is critical to + recompile the host build after upgrading the Dart SDK (e.g. via a `gclient sync` after + merging up to head), since artifacts from the host build need to be version matched to + artifacts in the Android/iOS build. +- Web, Desktop, and Fuchsia builds have only one build target (i.e. `host` or `fuchsia`). +- Make sure to exclude the `out` directory from any backup scripts, as many large binary + artifacts are generated. This is also generally true for all of the directories outside + of the `engine/src/flutter` directory. + +## Using a custom Dart SDK + +When targeting the host and desktop, on CI we use a pre-built Dart SDK vended by the Dart team. +To build and use the SDK from the Dart sources downloaded by `gclient sync`, after editing those +source files, pass the flag `--no-prebuilt-dart-sdk` to `//flutter/tools/gn`. + +## Compiling for Android (from macOS or Linux) + +These steps build the engine used by `flutter run` for Android devices. + +Run the following steps, from the `src` directory created in [Setting up the Engine development environment](Setting-up-the-Engine-development-environment.md): + +1. `git pull upstream main` in `src/flutter` to update the Flutter Engine repo. + +2. `gclient sync` to update dependencies. + +3. Prepare your build files + * `./flutter/tools/gn --android --unoptimized` for device-side executables. + * `./flutter/tools/gn --android --android-cpu arm64 --unoptimized` for newer 64-bit Android devices. + * `./flutter/tools/gn --android --android-cpu x86 --unoptimized` for x86 emulators. + * `./flutter/tools/gn --android --android-cpu x64 --unoptimized` for x64 emulators. + * `./flutter/tools/gn --unoptimized` for host-side executables, needed to compile the code. + * On Apple Silicon ("M" chips), add `--mac-cpu arm64` to avoid using emulation. This will generate `host_debug_unopt_arm64`. + +> 💡 **TIP**: When developing on a Mac with ARM (M CPU), prefer `host_debug_unopt_arm64`. +> +> You can continue to use `host_debug_unopt` (required for Intel Macs), but the engine will be run under Rosetta +> which may be slower. See [Developing with Flutter on Apple Silicon](../../platforms/desktop/macos/Developing-with-Flutter-on-Apple-Silicon.md) +> for more information. + +4. Build your executables + * `ninja -C out/android_debug_unopt` for device-side executables. + * `ninja -C out/android_debug_unopt_arm64` for newer 64-bit Android devices. + * `ninja -C out/android_debug_unopt_x86` for x86 emulators. + * `ninja -C out/android_debug_unopt_x64` for x64 emulators. + * `ninja -C out/host_debug_unopt` (or `ninja -C out/host_debug_unopt_arm64`, see above) for host-side executables. + * These commands can be combined. Ex: `ninja -C out/android_debug_unopt && ninja -C out/host_debug_unopt` + * For MacOS, you will need older version of XCode(9.4 or below) to compile android_debug_unopt and android_debug_unopt_x86. If you only care about x64, you can ignore this + +This builds a debug-enabled ("unoptimized") binary configured to run Dart in +checked mode ("debug"). There are other versions, see [Flutter's modes](../Flutter's-modes.md). + +If you're going to be debugging crashes in the engine, make sure you add +`android:debuggable="true"` to the `` element in the +`android/AndroidManifest.xml` file for the Flutter app you are using +to test the engine. + +See [The flutter tool](../../tool/README.md) for instructions on how to use the `flutter` tool with a local engine. +You will typically use the `android_debug_unopt` build to debug the engine on a device, and +`android_debug_unopt_x64` to debug in on a simulator. Modifying dart sources in the engine will +require adding a `dependency_override` section in you app's `pubspec.yaml` as detailed +[here](../../tool/README.md#using-a-locally-built-engine-with-the-flutter-tool). + +Note that if you use particular android or ios engine build, you will need to have corresponding +host build available next to it: if you use `android_debug_unopt`, you should have built `host_debug_unopt`, +`android_profile` -> `host_profile`, etc. One caveat concerns cpu-flavored builds like `android_debug_unopt_x86`: you won't be able to build `host_debug_unopt_x86` as that configuration is not supported. What you are expected to do is to build `host_debug_unopt` and symlink `host_debug_unopt_x86` to it. + +### Compiling everything that matters on Linux + +The following script will update all the builds that matter if you're developing on Linux and testing on Android and created the `.gclient` file in `~/dev/engine`: + +```bash +set -ex + +cd ~/dev/engine/src/flutter +git fetch upstream +git rebase upstream/main +gclient sync +cd .. + +flutter/tools/gn --unoptimized --runtime-mode=debug +flutter/tools/gn --android --unoptimized --runtime-mode=debug +flutter/tools/gn --android --runtime-mode=profile +flutter/tools/gn --android --runtime-mode=release + +cd out +find . -mindepth 1 -maxdepth 1 -type d | xargs -n 1 sh -c 'ninja -C $0 || exit 255' +``` +For `--runtime-mode=profile` build, please also consider adding `--no-lto` option to the `gn` command. It will make linking much faster with a small sacrifice on the binary size and memory usage (which probably doesn't matter for debugging or performance benchmark purposes.) + +## Compiling for iOS (from macOS) + +These steps build the engine used by `flutter run` for iOS devices. + +Run the following steps, from the `src` directory created in the steps above: + +1. `git pull upstream main` in `src/flutter` to update the Flutter Engine repo. + +2. `gclient sync` to update dependencies. + +3. `./flutter/tools/gn --ios --unoptimized` to prepare build files for device-side executables (or `--ios --simulator --unoptimized` for simulator). + * This also produces an Xcode project for working with the engine source code at `out/ios_debug_unopt/flutter_engine.xcodeproj` + * For a discussion on the various flags and modes, see [Flutter's modes](../Flutter's-modes.md). + * Add the `--simulator-cpu=arm64` argument for an arm64 Mac simulator to output to `out/ios_debug_sim_unopt_arm64`. + +4. `./flutter/tools/gn --unoptimized` to prepare the build files for host-side executables. + * On Apple Silicon ("M" chips), add `--mac-cpu arm64` to avoid using emulation. This will generate `host_debug_unopt_arm64`. + +5. `ninja -C out/ios_debug_unopt && ninja -C out/host_debug_unopt` to build all artifacts (use `out/ios_debug_sim_unopt` for Simulator). + +See [The flutter tool](../../tool/README.md) for instructions on how to use the `flutter` tool with a local engine. +You will typically use the `ios_debug_unopt` build to debug the engine on a device, and +`ios_debug_sim_unopt` to debug in on a simulator. Modifying dart sources in the engine will +require adding a `dependency_override` section in you app's `pubspec.yaml` as detailed +[here](../../tool/README.md#using-a-locally-built-engine-with-the-flutter-tool). + +See also [instructions for debugging the engine in a Flutter app in Xcode](../Debugging-the-engine.md#debugging-ios-builds-with-xcode). + +## Compiling for macOS or Linux + +These steps build the desktop embedding, and the engine used by `flutter test` on a host workstation. + +1. `git pull upstream main` in `src/flutter` to update the Flutter Engine repo. + +2. `gclient sync` to update your dependencies. + +3. `./flutter/tools/gn --unoptimized` to prepare your build files. + * `--unoptimized` disables C++ compiler optimizations. On macOS, binaries are emitted unstripped; on Linux, unstripped binaries are emitted to an `exe.unstripped` subdirectory of the build. + +4. `ninja -C out/host_debug_unopt` to build a desktop unoptimized binary. + * If you skipped `--unoptimized`, use `ninja -C out/host_debug` instead. + +See [The flutter tool](../../tool/README.md) for instructions on how to use the `flutter` tool with a local engine. +You will typically use the `host_debug_unopt` build in this setup. Modifying dart sources in the engine will +require adding a `dependency_override` section in you app's `pubspec.yaml` as detailed +[here](../../tool/README.md#using-a-locally-built-engine-with-the-flutter-tool). + + +## Compiling for Windows + +> [!WARNING] +> You can only build selected binaries on Windows (mainly `gen_snapshot` and the desktop embedding). + +On Windows, ensure that the engine checkout is not deeply nested. This avoid the issue of the build scripts working with excessively long paths. + +1. Make sure you have Visual Studio installed (non-Googlers only). [Debugging Tools for Windows 10](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools#small-classic-windbg-preview-logo-debugging-tools-for-windows-10-windbg) must be installed. + +2. `git pull upstream main` in `src/flutter` to update the Flutter Engine repo. + +3. Ensure long path support is enabled on your machine. Launch PowerShell as an administrator and run: +``` +Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -Force +``` + +4. If you are not a Google employee, you must set the following environment variables to point the depot tools at Visual Studio: +```shell +DEPOT_TOOLS_WIN_TOOLCHAIN=0 +GYP_MSVS_OVERRIDE_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community" # (or your location for Visual Studio) +WINDOWSSDKDIR="C:\Program Files (x86)\Windows Kits\10" # (or your location for Windows Kits) +``` +Also, be sure that Python27 is before any other python in your Path. + +5. `gclient sync` to update your dependencies. + +6. switch to `src/` directory. + +7. `python .\flutter\tools\gn --unoptimized` to prepare your build files. + * If you are only building `gen_snapshot`: `python .\flutter\tools\gn [--unoptimized] --runtime-mode=[debug|profile|release] [--android]`. + +8. `ninja -C .\out\

` to build. + * If you used a non-debug configuration, use `ninja -C .\out\ gen_snapshot`. + Release and profile are not yet supported for the desktop shell. + +## Compiling for Fuchsia + +### Build components for Fuchsia + +1. Building fuchsia is only supported on linux. You need to run `gclient config --custom-var=download_fuchsia_deps=True` then `gclient sync`. + +It will set `"download_fuchsia_deps": True` in `"custom_vars"` section in `.gclient` file, and download necessary binaries to build fuchsia components. + +2. If you'd like to run tests locally, also run `gclient config --custom-var=run_fuchsia_emu=True` then `gclient sync`. + +It will set `"run_fuchsia_emu": True` in `"custom_vars"` section in `.gclient` file, and download necessary binaries and images to run tests on fuchsia emulators. +You can set both `custom_vars` and run `gclient sync` only once. + +You will also need kvm enabled, or nested virtualization on the gcloud VMs. Fuchsia and the tests will all be executed on the qemu. + +3. Prepare and build + +``` +./flutter/tools/gn --fuchsia --no-lto +``` + + * It will create a `out/fuchsia_debug_x64`. + * Use `--fuchsia-cpu arm64` to build components for arm64. It will be created in a folder `out/fuchsia_debug_arm64`. + * Use `--runtime-mode=release` or `--runtime-mode=profile` to select other profiles as other platforms. + * Ignore `--no-lto` to use lto or link-time optimization. + +``` +ninja -C out/fuchsia_debug_x64 -k 0 +``` + + * It builds all but ignores known errors. + * Or specify following targets to avoid using `-k 0`. + +``` +flutter/shell/platform/fuchsia:fuchsia \ +flutter/shell/platform/fuchsia/dart_runner:dart_runner_tests \ +fuchsia_tests +``` + + * Use `autoninja` if it's available. + * `-C out/fuchsia_release_x64` for release build; other configurations are similar with a different folder name in `out/`. + +4. Run all tests locally + +``` +python3 flutter/tools/fuchsia/with_envs.py flutter/testing/fuchsia/run_tests.py +``` + + * It runs the tests in `out/fuchsia_debug_x64` by default. According to the configuration, it may take 5 minutes with regular gtest output to the terminal. + * Add `fuchsia_release_x64` at the end of the command for release build; other configurations are similar with a different folder name in `out/`. + +## Compiling for the Web + +For building the engine for the Web we use the [felt](https://github.com/flutter/engine/blob/main/lib/web_ui/README.md) tool. + +To test Flutter with a local build of the Web engine, add `--local-web-sdk=wasm_release` to your `flutter` command, e.g.: + +``` +flutter run --local-web-sdk=wasm_release -d chrome +flutter test --local-web-sdk=wasm_release test/path/to/your_test.dart +``` + +## Compiling for the Web on Windows + +Compiling the web engine might take a few extra steps on Windows. Use cmd.exe and "run as administrator". + +1. Make sure you have Visual Studio installed. Set the following environment variables. For Visual Studio use the path of the version you installed. + * `GYP_MSVS_OVERRIDE_PATH = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community"` + * `GYP_MSVS_VERSION = 2017` +2. Make sure, depot_tools, ninja and python are installed and added to the path. Also set the following environment variable for depot tools: + * `DEPOT_TOOLS_WIN_TOOLCHAIN = 0` + * Tip: if you get a python error try to use Python 2 instead of 3 +3. `git pull upstream main` in `src/flutter` to update the Flutter Engine repo. +4. `gclient sync` to update your dependencies. + * Tip: If you get a git authentication errors on this step try Git Bash instead +5. `python .\flutter\tools\gn --unoptimized --full-dart-sdk` to prepare your build files. +6. `ninja -C .\out\` to build. + +To test Flutter with a local build of the Web engine, add `--local-web-sdk=wasm_release` to your `flutter` command, e.g.: + +``` +flutter run --local-web-sdk=wasm_release -d chrome +flutter test --local-web-sdk=wasm_release test/path/to/your_test.dart +``` + +For testing the engine again use [felt](https://github.com/flutter/engine/blob/main/lib/web_ui/README.md) tool +this time with felt_windows.bat. + +``` +felt_windows.bat test +``` + +## Compiling for testing + +### Dart tests + +To run dart tests, build the engine: + +``` +flutter/tools/gn --unoptimized +ninja -C out/host_debug_unopt/ +``` + +execute `run_tests` for native: +``` +python3 flutter/testing/run_tests.py --type dart +``` + +and `felt` for web: +``` +cd flutter/lib/web_ui +dev/felt test [test file] +``` + + +## Troubleshooting Compile Errors + +### Version Solving Failed + +From time to time, as the Dart versions increase, you might see dependency errors such as: + +``` +The current Dart SDK version is 2.7.0-dev.0.0.flutter-1ef444139c. + +Because ui depends on 1.0.0 which requires SDK version >=2.7.0 <3.0.0, version solving failed. +``` + +Running `gclient sync` does not update the tags, there are two solutions: +1. under `engine/src/third_party/dart` run `git fetch --tags origin` +2. or run gclient sync with with tags parameter: `gclient sync --with_tags` + +_See also: [Debugging the engine](../Debugging-the-engine.md), which includes instructions on running a Flutter app with a local engine._ diff --git a/docs/contributing/Setting-up-the-Engine-development-environment.md b/docs/contributing/Setting-up-the-Engine-development-environment.md new file mode 100644 index 0000000000000..6bf60feeb019c --- /dev/null +++ b/docs/contributing/Setting-up-the-Engine-development-environment.md @@ -0,0 +1,176 @@ +_If you've already built the engine and have the configuration set up but merely need a refresher on +actually compiling the code, see [Compiling the engine](Compiling-the-engine.md)._ + +_If you are checking these instructions to refresh your memory and your fork of the engine is stale, +make sure to merge up to HEAD before doing a `gclient sync`._ + +# Getting dependencies + +Make sure you have the following dependencies available: + + * A Linux, macOS, or Windows host + * Linux supports cross-compiling artifacts for Android and Fuchsia, but not iOS. + * macOS supports cross-compiling artifacts for Android and iOS. + * Windows doesn't support cross-compiling artifacts for any of Android, Fuchsia, or iOS. + * `git` (used for source version control). + * An ssh client (used to authenticate with GitHub). + * `python3` (used by many of our tools, including `gclient`). + * **Chromium's + [depot_tools](https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up)** (Which includes gclient) + * Add the `depot_tools` directory to the *front* of your `PATH`. + * On macOS and Linux: `curl` and `unzip` (used by `gclient sync`). + * On Linux: The `pkg-config` package. + * On Windows: + - Visual Studio 2017 or later (required for non-Googlers only). + - [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/) (required for non-Googlers only). Be sure to install the "Debugging Tools for Windows" feature. + * On macOS: + - Install the latest Xcode. + - On Apple Silicon arm64 Macs, install the Rosetta translation environment by running `softwareupdate --install-rosetta`. + - Install Oracle's Java JDK, version 1.8 or later. + +You do not need to install [Dart](https://www.dartlang.org/downloads/linux.html). +A Dart toolchain is automatically downloaded as part of the "Getting the source" +step. Similarly for the Android SDK, it is downloaded by the `gclient sync` step below. + +## Getting the source + +Run the following steps to set up your environment: + +> [!IMPORTANT] +> Non-Googler Windows users should set the following environment variables to point +> `depot_tools` to their Visual Studio installation directory: +> * `DEPOT_TOOLS_WIN_TOOLCHAIN=0` +> * `GYP_MSVS_OVERRIDE_PATH=C:\Program Files\Microsoft Visual Studio\2022\Community` +> * Use the path of your installation. + +Create a new directory to hold the source code and move into it. Here, we are using the "engine" directory. +```sh +mkdir engine; cd engine; +``` + +> [!IMPORTANT] +> On Windows, the following must be run as an Administrator due to [a known issue](https://github.com/flutter/flutter/issues/94580). + +Fetch the Flutter engine sources. This may take a while on a slow connection. Do **not** interrupt this process. Otherwise, a partial checkout cannot be resumed and you'll have to delete all the files including the hidden files in the engine directory and start over. +```sh +fetch flutter +``` +The [Flutter Engine](https://github.com/flutter/engine) repository resides at `src/flutter`. The convention is to refer to this repository as `upstream`. + +```sh +git -C src/flutter remote rename origin upstream +``` + +Optionally, if you are working with a fork of the engine, add that as a Git remote. + +```sh +git -C src/flutter remote add origin +``` + +The "Engine Tool" called `et` is useful when working with the engine. It is located in the `flutter/bin` directory in the source checkout. Add this to your `$PATH` in your `.rc`. + +### Additional Steps for Web Engine + +Amend the generated `.gclient` file in the root of the source directory to add the following: +``` +solutions = [ + { + # Same as above... + "custom_vars": { + "download_emsdk": True, + }, + }, +] +``` + +Now, run + +```sh +gclient sync +``` + +## Next steps: + + * [Compiling the engine](Compiling-the-engine.md) explains how to actually get builds, now that you have the code. + * [The flutter tool](../../tool/README.md) has a section explaining how to use custom engine builds. + * [Signing commits](../../contributing/Signing-commits.md), to configure your environment to securely sign your commits. + +## Editor autocomplete support + +### Xcode [Objective-C++] + +On Mac, you can simply use Xcode (e.g., `open out/host_debug_unopt/products.xcodeproj`). + +### VSCode with C/C++ Intellisense [C/C++] + +VSCode can provide some IDE features using the [C/C++ extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools). It will provide basic support on install without needing any additional configuration. There will probably be some issues, like header not found errors and incorrect jump to definitions. + +Intellisense can also use our `compile_commands.json` for more robust functionality. Either symlink `src/out/compile_commands.json` to the project root at `src` or provide an absolute path to it in the `c_cpp_properties.json` config file. See ["compile commands" in the c_cpp_properties.json reference](https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference). This will likely resolve the basic issues mentioned above. + +For example, in `src/.vscode/settings.json`: + +```json +{ + "clangd.path": "buildtools/mac-arm64/clang/bin/clangd", + "clangd.arguments": [ + "--compile-commands-dir=out/host_debug_unopt_arm64" + ], + "clang-format.executable": "buildtools/mac-arm64/clang/bin/clang-format" +} +``` + +... which is built with: + +```shell +# M1 Mac (host_debug_unopt_arm64) +./tools/gn --unopt --mac-cpu arm64 --enable-impeller-vulkan --enable-impeller-opengles --enable-unittests +``` + +For adding IDE support to the Java code in the engine with VSCode, see ["Using VSCode as an IDE for the Android Embedding"](#using-vscode-as-an-ide-for-the-android-embedding-java). + +### Zed Editor + +[Zed](https://zed.dev/) can be used to edit C++ code in the Engine. To enable analysis and auto-completion, symlink `src/out/compile_commands.json` to the project root at `src`. + +### cquery/ccls (multiple editors) [C/C++/Objective-C++] + +Alternatively, [cquery](https://github.com/cquery-project/cquery) and a derivative [ccls](https://github.com/MaskRay/ccls) are highly scalable C/C++/Objective-C language server that supports IDE features like go-to-definition, call hierarchy, autocomplete, find reference etc that works reasonably well with our engine repo. + +They(https://github.com/cquery-project/cquery/wiki/Editor-configuration) [supports](https://github.com/MaskRay/ccls/wiki/Editor-Configuration) editors like VSCode, emacs, vim etc. + +To set up: +1. Install cquery + 1. `brew install cquery` or `brew install ccls` on osx; or + 1. [Build from source](https://github.com/cquery-project/cquery/wiki/Getting-started) +1. Generate compile_commands.json which our GN tool already does such as via `src/flutter/tools/gn --ios --unoptimized` +1. Install an editor extension such as [VSCode-cquery](https://marketplace.visualstudio.com/items?itemName=cquery-project.cquery) or [vscode-ccls](https://marketplace.visualstudio.com/items?itemName=ccls-project.ccls) + 1. VSCode-query and vscode-ccls requires the compile_commands.json to be at the project root. Copy or symlink `src/out/compile_commands.json` to `src/` or `src/flutter` depending on which folder you want to open. + 1. Follow [Setting up the extension](https://github.com/cquery-project/cquery/wiki/Visual-Studio-Code#setting-up-the-extension) to configure VSCode-query. + +![](https://media.giphy.com/media/xjIrToRDVvMPvjkBcl/giphy.gif) + +### Using VSCode as an IDE for the Android Embedding [Java] + +1. Install the extensions vscjava.vscode-java-pack (Extension Pack for Java) and vscjava.vscode-java-dependency (Project Manager for Java). + +1. Right click on the `shell/platform/android` folder in the engine source and click on `Add Folder to Java Source Path`. This creates an anonymous workspace and turns those files from ["syntax mode"](https://code.visualstudio.com/docs/java/java-project#_syntax-mode) to "compile mode". At this point, you should see a lot of errors since none of the external imports are found. + +1. Find the "Java Dependencies" pane in your Explorer view. Use the "Explorer: Focus on Java Dependencies View" command if hidden. + +1. Refresh the view and find the "flutter_*" project. There should be a "_/shell/platform/android" source folder there. + +1. In the "Referenced Libraries" sibling node, click the + button, navigate to `engine/src/third_party/android_embedding_dependencies` and add the entire folder. This is the equivalent of adding + ``` + "java.project.referencedLibraries": [ + "{path to engine}/src/third_party/android_embedding_dependencies/lib/**/*.jar" + ] + ``` + to your VSCode's settings.json for your user or for your workspace. + +1. If you previously had a `shell/platform/android/.classpath`, delete it. + +## VSCode Additional Useful Configuration + +1. Create [snippets](https://code.visualstudio.com/docs/editor/userdefinedsnippets) for header files with [this configuration](https://github.com/chromium/chromium/blob/master/tools/vscode/settings.json5). This will let you use `hdr` keyboard macro to create the boiler plate header code. Also consider some of [these settings](https://github.com/chromium/chromium/blob/master/tools/vscode/settings.json5) and [more tips](https://chromium.googlesource.com/chromium/src/+show/lkgr/docs/vscode.md). + +2. To format GN files on save, [consider using this extension](https://marketplace.visualstudio.com/items?itemName=persidskiy.vscode-gnformat). \ No newline at end of file diff --git a/docs/impeller/Flutter-GPU.md b/docs/impeller/Flutter-GPU.md new file mode 100644 index 0000000000000..676f0b426b661 --- /dev/null +++ b/docs/impeller/Flutter-GPU.md @@ -0,0 +1,49 @@ +**Flutter GPU** (previously referred to as "Dart GPU" or "Impeller Dart") is an effort to expose a low level graphics API in the Flutter Framework. + +Design doc: https://flutter.dev/go/impeller-dart + +Flutter GPU's runtime is a thin wrapper over [Impeller](README.md)'s HAL, from which custom renderers may be entirely built using Dart. Just like with Impeller, Flutter GPU shader bundles are compiled ahead of time using [impellerc](https://github.com/flutter/engine/tree/main/impeller/compiler). As such, Flutter GPU is only available on platforms that support Impeller. + +## Dart FFI + +Under the hood, the API communicates with Flutter Engine via Dart FFI, calling symbols publicly exported by libflutter and/or embedders. These symbols are prefixed with `InternalFlutterGpu`, and are considered unstable. Direct usage of the exported symbols is not supported and will break without notice; the only supported way to use Flutter GPU is by importing `package:flutter_gpu`. + +## Try out Flutter GPU + +Once released, Flutter GPU will be shipped as part of the Flutter SDK in the form of a Dart package called `flutter_gpu`. An early implementation of the `flutter_gpu` package is being developed under the [`lib/gpu` directory](https://github.com/flutter/engine/tree/main/lib/gpu) of the Flutter Engine repository. + +> [!CAUTION] +> _All_ aspects of Flutter GPU are subject to breakage or removal at any time without prior deprecation notice or viable feature replacement. DO NOT rely on Flutter GPU for production projects at this time, but DO have fun playing with it and sharing your experiments with the community. + +Flutter GPU is currently unfinished, extremely experimental, and not well documented. [bdero](https://github.com/bdero) is actively developing and testing Flutter GPU against the MacOS desktop embedder; shader compilation and import likely don't function correctly on other platforms yet. However, if you wish to experiment with Flutter GPU, it is possible to do so without a custom Engine build: + +1. Update your Flutter checkout to the latest version in the [master channel](https://docs.flutter.dev/release/upgrade#other-channels). +1. Clone [Flutter Engine](https://github.com/flutter/engine) and checkout the Engine commit that the Flutter master channel is currently pinned to. This can be found in the [`bin/internal/engine.version` file](https://github.com/flutter/flutter/blob/main/bin/internal/engine.version) of the main Flutter repository. + ```sh + git clone https://github.com/flutter/engine.git + cd engine + git reset --hard [PINNED_ENGINE_COMMIT] + ``` +1. Create a new Flutter project using the Flutter tool and add `flutter_gpu` as a dependency in `pubspec.yaml` with a local path pointing to the `lib/gpu` directory within the Flutter Engine repository cloned in step 2. For example: + ```yaml + dependencies: + flutter: + sdk: flutter + flutter_gpu: + path: ../engine/src/flutter/lib/gpu + ``` +1. From here, you can import the API and begin using it. + ```dart + import 'package:flutter_gpu/gpu.dart' as gpu; + ``` + Check out this [examples repository](https://github.com/bdero/flutter-gpu-examples), which includes an example of [drawing a triangle](https://github.com/bdero/flutter-gpu-examples/blob/master/lib/triangle.dart), among other things. + +## Reporting bugs + +If you run into issues while using Flutter GPU, please file a bug using the standard [bug report template](https://github.com/flutter/flutter/issues/new?template=2_bug.yml). Additionally, mention "Flutter GPU" in the title, label the bug with the `e: impeller` label, and tag [bdero](https://github.com/bdero) in the issue description. + +## Questions or feedback? + +If you have non-bug report questions surrounding Flutter GPU, there are several ways you can reach out to the developer: +* Create a thread in the #help channel of the [Discord server](../../contributing/Chat.md). Place "Flutter GPU" in the title of the thread and tag @bdero in the message. +* Send a Twitter DM to [@algebrandon](https://twitter.com/algebrandon). diff --git a/docs/impeller/Impeller-Scene.md b/docs/impeller/Impeller-Scene.md new file mode 100644 index 0000000000000..dd09db8c79019 --- /dev/null +++ b/docs/impeller/Impeller-Scene.md @@ -0,0 +1,19 @@ +We are excited to have you tinker on [the Impeller Scene Demo presented at Flutter Forward](https://www.youtube.com/live/zKQYGKAe5W8?feature=share&t=7048). While we spend time learning the use-cases and finalizing the API, the functionality for Impeller Scene is behind a compile-time flag. During this time, there are no guarantees around API stability. + +**Compiling the Engine** + +- Configure your Mac host to compile the Flutter Engine by [following the guidance in wiki](../contributing/Setting-up-the-Engine-development-environment.md). +- Ensure that you are on the [main branch of the Flutter Engine](https://github.com/flutter/engine/tree/main). +- Ensure that you are on the [main branch of the Flutter Framework](https://github.com/flutter/flutter/tree/main). +- Configure the host build: `./flutter/tools/gn --enable-impeller-3d --no-lto` +- Configure the iOS build: `./flutter/tools/gn --enable-impeller-3d --no-lto --ios` + - Add the `--simulator --simulator-cpu=arm64` flag to the iOS build if you are going to test on the simulator. +- Build host artifacts (this will take a while): `ninja -C out/host_debug` +- Build iOS artifacts (this will take a while): `ninja -C out/ios_debug` + - If targeting the simulator: `ninja -C out/ios_debug_sim_arm64` +- Clone the demo repository: `git clone https://github.com/bdero/flutter-scene-example.git` and move into the directory. +- Plug in your device or open `Simulator.app`, then run `flutter devices` to note the device identifier. +- Run the demo application: `flutter run -d [device_id] --local-engine ios_debug --local-engine-host host_debug` (or `ios_debug_sim_arm64` if you are running on the Simulator). + - On Silicon Macs, prefer `--local-engine-host host_debug_arm64` (adjusting your `ninja` command above accordingly) + +We hope to continue evolving the API and have it available on the stable channel soon! diff --git a/docs/impeller/README.md b/docs/impeller/README.md new file mode 100644 index 0000000000000..0f04e700ad935 --- /dev/null +++ b/docs/impeller/README.md @@ -0,0 +1,7 @@ +_For user information about Flutter's new rendering backend, check out [Impeller preview](https://docs.flutter.dev/perf/impeller)._ + +Team-facing documentation specific to Impeller: + +- [Setting up MoltenVK on macOS for Impeller](Setting-up-MoltenVK-on-macOS-for-Impeller.md) +- [Flutter GPU](Flutter-GPU.md) +- [Instructions for playing with the Impeller Scene demo|Impeller Scene](Impeller-Scene.md) diff --git a/docs/impeller/Setting-up-MoltenVK-on-macOS-for-Impeller.md b/docs/impeller/Setting-up-MoltenVK-on-macOS-for-Impeller.md new file mode 100644 index 0000000000000..2c0231e137c78 --- /dev/null +++ b/docs/impeller/Setting-up-MoltenVK-on-macOS-for-Impeller.md @@ -0,0 +1,7 @@ +- Get the MoltenVK SDK from https://vulkan.lunarg.com/sdk/home#mac. +- Make sure to check off `System Global Installation`: +image + +- When running `flutter/tools/gn`, add the `--impeller-enable-vulkan` flag, e.g. `./flutter/tools/gn --impeller-enable-vulkan --unopt --mac-cpu arm64` + +You should now be able to build and run the Vulkan host tests, e.g. `out/host_debug_unopt_arm64/impeller_unittests --gtest_filter="*Vulkan*"`. diff --git a/docs/release/Code-signing-metadata.md b/docs/release/Code-signing-metadata.md new file mode 100644 index 0000000000000..4efd26a13ad49 --- /dev/null +++ b/docs/release/Code-signing-metadata.md @@ -0,0 +1,196 @@ +# Code signing + +This covers the process of how to add / update code signing metadata of flutter +engine binaries. + +## Overview + +Flutter engine binaries are built with GN and ninja, referencing pre-defined +configurations such as ci/builders +[JSON files](https://github.com/flutter/engine/blob/main/ci/builders/mac_host_engine.json). +During flutter releases, engineers need to code sign mac engine binaries to +assure users that they come from a known source, have not been tampered with, +and should not be quarantined by Gatekeepers. + +Each of the Flutter engine binaries are either code signed with entitlements, or +code signed without entitlements. (An entitlement, along with information from +the developer account, grant particular permissions to binaries, such as +capability to access the user's home automation network.) For example, impellerc +is code signed with flutter entitlements, whereas .dylib files are usually code +signed without entitlements. + +## Add / Update code signing metadata + +### Glossary + +1. BUILD.gn files: files that include build rules of GN targets. An example is + the + [BUILD.gn file of flutter engine](https://github.com/flutter/engine/blob/main/BUILD.gn). +2. leaf node of an engine binary: the minimal gn target that could produce such + an engine binary. That is, this target does not have any dependencies on + other gn targets that could build this engine binary. +3. dependencies: Every gn target could have dependencies on other gn targets. + The dependency of a gn target is defined in the `deps` field of the target's + build rule. + +### ways to generate engine binary + +Generally, there are two ways to generate an engine binary: + +1. Through build rules defined in BUILD.gn files. + +2. Through global generator scripts. (these scripts are normally .py files) + +To distinguish between the two, an engine binary is built through global +generator if it is listed in the `archives` -> `destination` field of the +builder JSON +([mac_ios_engine.json](https://github.com/flutter/engine/blob/main/ci/builders/mac_ios_engine.json) +or +[mac_host_engine.json](https://github.com/flutter/engine/blob/main/ci/builders/mac_host_engine.json)). +For example, `darwin-x64/FlutterEmbedder.framework.zip`. Whereas binaries built +with BUILD.gn files are listed among the `builds` field of the JSON file. For +example, `darwin-x64/artifacts.zip`. We will provide examples for both +scenarios. + +### To add / update code signing metadata in BUILD.gn files: + +1. Find the leaf node where the target engine binary is built. To do so, + Recursively trace the `deps` field of the engine artifact. The paths in + `deps` field of the GN target correspond to the paths of other GN targets + that are dependencies of the current GN target. + +2. Add / Update the `metadata` field of the leaf node. For a new engine binary: + + 2.1 if it should be code signed with entitlements, add [the name of the + engine binary] to the `entitlement_file_path` field in `metadata` . + + 2.2 if the binary shouldn't be code signed with entitlements, add [the name + of the engine binary] to the `without_entitlement_file_path` field in + `metadata` . + +3. If a `entitlement_file_path` or a `without_entitlement_file_path` field does + not exist: + + **note**: this step is only needed if the target includes solely binaries + that have never been code signed before. This step also requires some + background on flutter engine and gn build rules. + + Add a `metadata` field in the gn target of the leaf node, and put the name + of the binary in this field. e.g. + + ``` + metadata = { + entitlement_file_path = [ "libtessellator.dylib" ] + } + ``` + + In the same file that produces the engine artifact(zip file), add a build + rule to collect the data keys. e.g. + + ``` + generated_file("artifacts_entitlement_config") { + outputs = [ "$target_gen_dir/entitlements.txt" ] + + data_keys = [ "entitlement_file_path" ] + + deps = [ "//flutter/lib/snapshot:generate_snapshot_bin" ] + if (flutter_runtime_mode == "debug") { + deps += [ + "//flutter/impeller/compiler:impellerc", + "//flutter/impeller/tessellator:tessellator_shared", + "//flutter/shell/testing:testing", + "//flutter/tools/path_ops:path_ops", + ] + } + } + ``` + + Finally, embed the file with collected data keys in the zip artifact. e.g. + + ``` + if (host_os == "mac") { + deps += [ ":artifacts_entitlement_config" ] + files += [ + { + source = "$target_gen_dir/entitlements.txt" + destination = "entitlements.txt" + }, + ] + } + ``` + +#### Example + +Suppose impellerc is a binary that exist in a zip bundle called artifacts.zip. +Then impellerc is the name of the binary, and artifacts.zip is the flutter +engine artifact. + +1. Following step 1, the `deps` field of the GN target of artifacts.zip + includes the path of impeller dependency: + `//flutter/impeller/compiler:impellerc`. Following this path, we locate the + GN file at `flutter/impeller/compiler/BUILD.gn`, and find the leaf node that + builds impellerc: `impeller_component("impellerc")`. + +2. Following step 2, since `impellerc` should be code signed with entitlements, + we go to the `metadata` field of the impellerc target, and add the name + `impellerc` to the `entitlement_file_path` array inside the `metadata` + field. + +You can reference the +[BUILD.gn file of impellerc](https://github.com/flutter/engine/blob/main/impeller/compiler/BUILD.gn). + +### To add / update code signing metadata in global generator files: + +1. Find the generator script path listed under `generators` -> `tasks` -> + `script` of the ci/builder JSON files + ([mac_ios_engine.json](https://github.com/flutter/engine/blob/main/ci/builders/mac_ios_engine.json) + or + [mac_host_engine.json](https://github.com/flutter/engine/blob/main/ci/builders/mac_host_engine.json)). + + The generator script related to iOS is located at + `sky/tools/create_full_ios_framework.py`, and generator script related to + macOS is located at `sky/tools/create_macos_framework.py`. + +2. Add / Update the variables ending with `with_entitlements` / + `without_entitlements` suffix from the generator script you found in step + one. + + As an example, you can find variables `ios_file_without_entitlements` and + `ios_file_with_entitlements` in sky/tools/create_full_ios_framework.py; and + find variables `filepath_without_entitlements` and + `filepath_with_entitlements` in sky/tools/create_macos_framework.py + + 2.1 if the binary should be code signed with entitlements, add [the name of + the binary] to the variable name with the `with_entitlements` suffix. + (`ios_file_with_entitlements` or `filepath_with_entitlements` depending on + which script) + + 2.2 if the binary shouldn't be code signed with entitlements, add [the name + of the binary] to the variable name with the `without_entitlements` suffix. + +#### Example + +Suppose `Flutter.xcframework/ios-arm64/Flutter.framework/Flutter` is a binary +that exist in a zip bundle called `ios/artifacts.zip`. + +1. Following step 1, in + [mac_ios_engine.json](https://github.com/flutter/engine/blob/main/ci/builders/mac_ios_engine.json), + it builds the artifact with the + `flutter/sky/tools/create_full_ios_framework.py` script. + +2. Following step 2, since + `Flutter.xcframework/ios-arm64/Flutter.framework/Flutter` shouldn't be code + signed with entitlements, we add the binary name + `Flutter.xcframework/ios-arm64/Flutter.framework/Flutter` to the + `ios_file_without_entitlements` variable. + +You can reference the generator script +[create_full_ios_framework.py](https://github.com/flutter/engine/blob/main/sky/tools/create_full_ios_framework.py). + +## Code signing artifacts other than flutter engine binaries + +The code signing functionality is implemented as [a recipe module in flutter recipes](https://cs.opensource.google/flutter/recipes/+/master:recipe_modules/signing/api.py). Therefore it can also be used to +code sign arbitrary flutter artifacts built through recipe, for example, flutter iOS usb dependencies. + +To code sign, after the artifacts are built, pass the file paths into +the code signing recipe module and invoke the function. An example is [how engine V2 invokes the code signing recipe module](https://cs.opensource.google/flutter/recipes/+/master:recipes/engine_v2/engine_v2.py;l=197-212). \ No newline at end of file diff --git a/docs/testing/Testing-the-engine.md b/docs/testing/Testing-the-engine.md new file mode 100644 index 0000000000000..4426f805736d5 --- /dev/null +++ b/docs/testing/Testing-the-engine.md @@ -0,0 +1,350 @@ +## Testing the engine + +Pull requests submitted to the [engine repository](https://github.com/flutter/engine) +should be tested to prevent functional regressions. + +This guide describes how to write and run various types of tests in the engine. + +## C++ - core engine + +If you edit `.cc` files in https://github.com/flutter/engine/tree/main, +you're working on the core, portable Flutter engine. + +### Unit tests + +C++ unit tests are co-located with their header and source files. For instance, +`fml/file.h` and `fml/file.cc` have a `fml/file_unittest.cc` in the same +directory. When editing C++ files, look for its `_unittest.cc` sibling or create +one if there isn't one present. + +The engine repo has a unified build system to build C, C++, Objective-C, +Objective-C++, and Java files using [GN](https://gn.googlesource.com/gn/) and +[Ninja](https://ninja-build.org/). Individual `_unittest.cc` files are +referenced by the `BUILD.gn` build rule located in the folder or in an ancestor +folder. + +You can run the C++ unit tests with: + +``` +testing/run_tests.py --type=engine +``` + +from the `flutter` directory, after building the engine variant to test +(by default `host_debug_unopt`). To use a different variant (e.g. if you use +an Apple Silicon Mac), run: + +``` +testing/run_tests.py --type=engine --variant=host_debug_unopt_arm64 +``` + +Behind the scenes, those tests in the same directory are built together as a +testonly executable when you build the engine variant. The `run_tests.py` script +executes them one by one. + +C++ unit tests are executed during pre-submit on our CI system when submitting +PRs to the `flutter/engine` repository. + +#### Google Tests + +C++ unit tests in the core engine uses the [Google Test](https://google.github.io/googletest/primer.html) +C++ testing framework to facilitate C++ test discovery, assertions, etc. + +Since the engine is portable, these unit tests are compiled and run directly +on and for your host machine architecture. + +It's best practice to test only one real production class per test and create +mocks for all other dependencies. + +## Java - Android embedding + +If you edit `.java` files in the https://github.com/flutter/engine/tree/main/shell/platform/android +directory, you're working on the Android embedding which connects the core C++ +engine to the Android SDK APIs and runtime. + +### Robolectric JUnit tests + +For testing logic within a class at a unit level, create or add to a JUnit test. + +Existing Java unit tests are located at https://github.com/flutter/engine/tree/main/shell/platform/android/test +and follow the Java package directory structure. Files in the `shell/platform/android/io/flutter/` +package tree can have a parallel file in the `shell/platform/android/test/io/flutter/` +package tree. Files in matching directories are considered [package visible](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) +as is the case in standard Java. + +When editing production files in `shell/platform/android/io/flutter/`, +the easiest step to add tests is to look for a matching `...Test.java` file in +`shell/platform/android/test/io/flutter/`. + +See the [Java unit test README](https://github.com/flutter/engine/blob/main/shell/platform/android/test/README.md) +for details. + +The engine repo has a unified build system to build C, C++, Objective-C, +Objective-C++, and Java files using [GN](https://gn.googlesource.com/gn/) and +[Ninja](https://ninja-build.org/). Because it doesn't use the more common +Gradle build system (which can't build C++ for instance), the tests and its +dependencies can't be directly built and run inside Android Studio like a +standard Android project. + +Instead, the engine provides the script: + +``` +testing/run_tests.py --type=java +``` + +to easily build and run the JUnit tests. + +This script only has a limited amount of smartness. If you've never built the engine before, it'll build the test and classes under test with a reasonable default configuration. If you've built the engine before, it'll re-build the engine with the same GN flags. You may want to double check your [GN flags](../contributing/Compiling-the-engine.md#compiling-for-android-from-macos-or-linux) if you haven't built the engine for a while. + +Behind the scenes, it invokes GN and Ninja to build a single .jar file +containing the test runner and dependencies. Then it uses the system `java` +runtime to execute the .jar. JDK v8 must be set as your `$JAVA_HOME` to run +the Robolectric tests. + +See [Setting-up-the-Engine-development-environment#using-vscode-as-an-ide-for-the-android-embedding-java](../dev/Setting-up-the-Engine-development-environment.md) +for tips on setting up Java code completion and syntax highlighting in Visual +Studio when working on the engine and tests. + +JUnit tests are executed during pre-submit on our CI system when submitting +PRs to the `flutter/engine` repository. + +#### Robolectric + +[Robolectric](http://robolectric.org/) is a standard Android testing library to +mock the Android runtime. It allows tests to be executed on a lightweight Java +JVM without booting a heavy Android runtime in an emulator. This allows for +rapid test iterations and allows our tests to run better on CI systems. + +All engine JUnit tests are Robolectric tests. This means all `android.*` imports +are mocked by Robolectric. If you need to modify how Android components (such as +an [android.view.View](https://developer.android.com/reference/android/view/View.html) +or an [android.app.Activity](https://developer.android.com/reference/android/app/Activity.html)) +behave in the test, see other tests for examples or see docs at +http://robolectric.org/ on how to interact with shadows. + +#### Mockito + +[Mockito](https://site.mockito.org/) is also a standard Android testing library +used to mock non-Android dependencies needed to construct and test interactions +with your your under-test production class. + +It's best practice to test only one real production class per test and +mock all other dependencies with mockito. + +The Mockito library is an available test dependency when writing Robolectric +tests. + +### Component integration tests + +Component tests test the interaction of multiple embedding Java classes together +but they don't test all production classes end-to-end. In the Android embedding +case, we test groups of Java classes by their function in `...ComponentTest.java` +files that are also in the `shell/platform/android/test/io/flutter/` +directory. C++ engine parts via JNI are not tested here. + +Component tests are also Robolectric JUnit tests and are invoked together with +unit tests when running: + +``` +testing/run_tests.py --type=java +``` + +JUnit component tests are executed during pre-submit on our CI system when +submitting PRs to the `flutter/engine` repository. + +### End-to-end tests + +End-to-end tests exercise the entire Android embedding with the C++ engine on +a real Android runtime in an emulator. It's an integration test ensuring that +the engine as a whole on Android is functioning correctly. + +The project containing the Android end-to-end engine test is at +https://github.com/flutter/engine/tree/main/testing/scenario_app/android. + +This test project is build similarly to a normal Flutter app. The Dart code is +compiled into AOT and the Android part is compiled via Gradle with a dependency +on the prebuilt local engine. The built app then installed and executed on an +emulator. + +Unlike a normal Flutter app, the Flutter framework on the Dart side is a +lightweight fake at https://github.com/flutter/engine/tree/main/testing/scenario_app/lib +that implements some of the basic functionalities of `dart:ui` Window rather +than using the real Flutter framework at `flutter/flutter`. + +The end-to-end test can be executed by running: + +``` +testing/scenario_app/run_android_tests.sh +``` + +Additional end-to-end instrumented tests can be added to https://github.com/flutter/engine/tree/main/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenarios. + +If supporting logic is needed for the test case, it can be added to the +Android app under-test in https://github.com/flutter/engine/tree/main/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios +or to the fake Flutter framework under-test in https://github.com/flutter/engine/tree/main/testing/scenario_app/lib. + +As best practice, favor adding unit tests if possible since instrumented tests +are, by nature, non-hermetic, slow and flaky. + +End-to-end tests on Android are run on presubmit for flutter/engine PRs. + +## Objective-C - iOS embedding + +If you edit `.h` or `.mm` files in the https://github.com/flutter/engine/tree/main/shell/platform/darwin/ios +directory, you're working on the iOS embedding which connects the core C++ +engine to the iOS SDK APIs and runtime. + +### XCTest unit tests + +For testing logic within a class in isolation, create or add to a XCTestCase. + +The iOS unit testing infrastructure is split in 2 different locations. The +`...Test.mm` files in https://github.com/flutter/engine/tree/main/shell/platform/darwin/ios +contain the unit tests themselves. The +https://github.com/flutter/engine/tree/main/testing/ios/IosUnitTests directory +contains an Xcode container project to execute the test. + +See the [iOS unit test README](https://github.com/flutter/engine/blob/main/testing/ios/IosUnitTests/README.md) +for details on adding new test files. + +The engine repo has a unified build system to build C, C++, Objective-C, +Objective-C++, and Java files using [GN](https://gn.googlesource.com/gn/) and +[Ninja](https://ninja-build.org/). Since GN and Ninja has to build the C++ +dependencies that the Objective-C classes reference, the tests aren't built by +the Xcode project in https://github.com/flutter/engine/tree/main/testing/ios/IosUnitTests. + +Instead, the engine provides the script: + +``` +testing/run_tests.py --type=objc +``` + +to easily build and run the XCTests. + +- Add the `--ios-variant ios_debug_sim_unopt_arm64` argument when using an arm64 Mac simulator (built with `--simulator-cpu=arm64`). + +This script only has a limited amount of smartness. If you've never built the engine before, it'll build the test and classes under test with a reasonable default configuration. If you've built the engine before, it'll re-build the engine with the same GN flags. You may want to double check your GN flags ([See compiling for ios from macos](../contributing/Compiling-the-engine.md#compiling-for-ios-from-macos)) if you haven't built the engine for a while. + +Behind the scenes, it invokes GN and Ninja to build the tests and dependencies +into a single `.dylib`. Then it uses Xcode and the Xcode project at +`testing/ios/IosUnitTests` to import and execute the XCTests in the `.dylib`. + +If you get an `AssertionError: libios_test_flutter.dylib doesn't exist` error, you may need to manually run the ninja command that is printed to the terminal. e.g. `ninja -C $FLUTTER_ENGINE/out/ios_debug_sim_unopt_arm64 ios_test_flutter` + +See [Setting-up-the-Engine-development-environment#editor-autocomplete-support](../dev/Setting-up-the-Engine-development-environment.md) +for tips on setting up C/C++/Objective-C code completion and syntax highlighting +when working on the engine and tests. + +To debug the XCTests, you can open the Xcode project at `testing/ios/IosUnitTests/IosUnitTests.xcodeproj` +and run the tests (such as via ⌘U). Note you cannot modify the test source and +build the tests in Xcode for reasons mentioned above. If you modify the test, +you need to run `testing/run_tests.py` again. + +XCTests are executed during pre-submit on our CI system when submitting PRs to +the `flutter/engine` repository. + +#### XCTest + +[XCTest](https://developer.apple.com/documentation/xctest) is the standard way +of creating unit tests in Xcode projects. Since iOS has x86 simulators and +since we can build x86 engines, we can execute the XCTests directly on macOS +in a headless simulator using the real iOS SDK. + +#### OCMock + +[OCMock](https://ocmock.org) is a standard iOS testing library used to mock +dependencies needed to construct and test interactions with your under-test +production class. + +It's best practice to test only one real production class per test and +mock all other dependencies with OCMock. + +The OCMock library is available as a test dependency when writing XCTests for +the engine. + +### End-to-end tests + +End-to-end tests exercise the entire iOS embedding with the C++ engine on +a headless iOS simulator. It's an integration test ensuring that +the engine as a whole on iOS is functioning correctly. + +The project containing the iOS end-to-end engine test is at +https://github.com/flutter/engine/tree/main/testing/scenario_app/ios. + +This test project is build similarly to a normal debug Flutter app. The Dart +code is bundled in JIT mode and is brought into Xcode with a `.framework` +dependency on the prebuilt local engine. It's then installed and executed on a +simulator via Xcode. + +Unlike a normal Flutter app, the Flutter framework on the Dart side is a +lightweight fake at https://github.com/flutter/engine/tree/main/testing/scenario_app/lib +that implements some of the basic functionalities of `dart:ui` Window rather +than using the real Flutter framework at `flutter/flutter`. + +The end-to-end test can be executed by running: + +``` +testing/scenario_app/run_ios_tests.sh +``` + +Additional end-to-end instrumented tests can be added to https://github.com/flutter/engine/tree/main/testing/scenario_app/ios/Scenarios/ScenariosTests. + +If supporting logic is needed for the test case, it can be added to the +Android app under-test in https://github.com/flutter/engine/tree/main/testing/scenario_app/ios/Scenarios/Scenarios +or to the fake Flutter framework under-test in https://github.com/flutter/engine/tree/main/testing/scenario_app/lib. + +As best practice, favor adding unit tests if possible since end-to-end tests +are, by nature, non-hermetic, slow and flaky. + +End-to-end tests on iOS are executed during pre-submit on our CI system when +submitting PRs to the `flutter/engine` repository. + +## Dart - dart:ui + +If you edit `.dart` files in https://github.com/flutter/engine/tree/main/lib/ui, +you're working on the 'dart:ui' package which is the interface between +the C++ engine and the Dart Flutter framework. + +### Unit tests + +Dart classes in https://github.com/flutter/engine/tree/main/lib/ui have matching +unit tests at https://github.com/flutter/engine/tree/main/testing/dart. + +When editing production files in the 'dart:ui' package, add to or create a +test file in `testing/dart`. + +To run the Dart unit tests, use the script: + +``` +testing/run_tests.py --type=dart +``` + +Behind the scenes, it invokes the engine repo's unified [GN](https://gn.googlesource.com/gn/) +and [Ninja](https://ninja-build.org/) build systems to use a version of the Dart +SDK specified in the `DEPS` file to create a `sky_engine` Dart package. Then it +compiles and runs each `_test.dart` file under `testing/dart`. + +To debug the test, open `src/out/ios_debug_sim_unopt/scenario_app/Scenarios.xcodeproj` in +Xcode and hit CMD+U. + +Dart unit tests are executed during pre-submit on our CI system when submitting +PRs to the `flutter/engine` repository. + +_See also: [Flutter Test Fonts](../../contributing/testing/Flutter-Test-Fonts.md)_ + +### Framework tests + +Dart tests in the `flutter/flutter` framework repo are also executed on top of +the `dart:ui` package and underlying engine. + +These tests are executed during pre-submit on our CI system when +submitting PRs to the `flutter/engine` repository. + +Assuming your `flutter` and `engine` working directories are siblings, you can run the framework tests locally using the following command from the root of your `flutter` repository: + +```bash +(cd packages/flutter; ../../bin/flutter test --local-engine=host_debug_unopt --local-engine-host=host_debug_unopt) +``` + +## Web engine + +Web tests are run via the `felt` command. More details can be found in [lib/web_ui/README.md](https://github.com/flutter/engine/blob/main/lib/web_ui/README.md#hacking-on-the-web-engine). From 9df5d733f2bdf2c318cb8137e537c334fd7f73ec Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Wed, 26 Jun 2024 13:40:04 -0700 Subject: [PATCH 43/88] Remove otherwise unused third_party/web_dependencies. (#53588) There are no usages other than the reference in the LICENSE checker. --- DEPS | 10 ---------- ci/licenses_golden/tool_signature | 2 +- tools/licenses/lib/paths.dart | 1 - 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/DEPS b/DEPS index 7c78247a4e3c6..0fae20f1dc53f 100644 --- a/DEPS +++ b/DEPS @@ -792,16 +792,6 @@ deps = { 'dep_type': 'cipd', }, - 'src/third_party/web_dependencies': { - 'packages': [ - { - 'package': 'flutter/web/canvaskit_bundle', - 'version': Var('canvaskit_cipd_instance') - } - ], - 'dep_type': 'cipd', - }, - 'src/third_party/java/openjdk': { 'packages': [ { diff --git a/ci/licenses_golden/tool_signature b/ci/licenses_golden/tool_signature index 9f794553b00cf..718ca28d0b2a4 100644 --- a/ci/licenses_golden/tool_signature +++ b/ci/licenses_golden/tool_signature @@ -1,2 +1,2 @@ -Signature: 44921bea6071222d521ad8c486a1bd58 +Signature: 8fcfb02b766e80ce50611b894f3fe047 diff --git a/tools/licenses/lib/paths.dart b/tools/licenses/lib/paths.dart index c37c01bdc7ce9..c13b87ba00238 100644 --- a/tools/licenses/lib/paths.dart +++ b/tools/licenses/lib/paths.dart @@ -223,7 +223,6 @@ final Set skippedPaths = { r'third_party/android_tools', // excluded on advice r'third_party/java', // only used for Android builds r'third_party/libxml', // dependency of the testing system that we don't actually use - r'third_party/web_dependencies/canvaskit', // redundant; covered by Skia dependencies r'tools', // not distributed in binary }; From b097a62af5dbfdb5ae0e4d419b44e60748d94d1f Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 16:42:09 -0400 Subject: [PATCH 44/88] Roll Skia from 0a979d9f3606 to 173ee0af82c9 (2 revisions) (#53593) https://skia.googlesource.com/skia.git/+log/0a979d9f3606..173ee0af82c9 2024-06-26 nathanasanchez@google.com [Graphite] Consolidate ssbo caps 2024-06-26 brianosman@google.com Fix asymmetry in lattice validation If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 0fae20f1dc53f..563f6ac7305f4 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '0a979d9f360659e034fee2395c9e12fa08dc7f5b', + 'skia_revision': '173ee0af82c961dd36f1a5255c3da59161e0590b', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 7c52a0f72c56e..2506b6bbc6bc1 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 27b98f44888fefbb6ad6d9aaf41c952f +Signature: ac498059c15e926631a2d448d5117daf ==================================================================================================== LIBRARY: etc1 From 7f81e71ec60cabe6d477614ea69bdf1f73067cda Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Wed, 26 Jun 2024 14:23:10 -0700 Subject: [PATCH 45/88] [Impeller] blur - cropped the downsample pass for backdrop filters (#53562) This should be no functional change, just makes the case of clipped backdrop filters take up less memory. fixes: https://github.com/flutter/flutter/issues/150713 test coverage: - the framework's "backdrop filter" test - GaussianBlurAnimatedBackdrop [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- .../filters/gaussian_blur_filter_contents.cc | 185 +++++++++++++----- 1 file changed, 131 insertions(+), 54 deletions(-) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index e5d9331b964c2..fe35f8f784cd3 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -156,6 +156,64 @@ std::optional GetSnapshot(const std::shared_ptr& input, return input_snapshot; } +/// Returns `rect` relative to `reference`, where Rect::MakeXYWH(0,0,1,1) will +/// be returned when `rect` == `reference`. +Rect MakeReferenceUVs(const Rect& reference, const Rect& rect) { + Rect result = Rect::MakeOriginSize(rect.GetOrigin() - reference.GetOrigin(), + rect.GetSize()); + return result.Scale(1.0f / Vector2(reference.GetSize())); +} + +Quad CalculateSnapshotUVs( + const Snapshot& input_snapshot, + const std::optional& source_expanded_coverage_hint) { + std::optional input_snapshot_coverage = input_snapshot.GetCoverage(); + Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)}; + FML_DCHECK(input_snapshot.transform.IsTranslationScaleOnly()); + if (source_expanded_coverage_hint.has_value() && + input_snapshot_coverage.has_value()) { + // Only process the uvs where the blur is happening, not the whole texture. + std::optional uvs = + MakeReferenceUVs(input_snapshot_coverage.value(), + source_expanded_coverage_hint.value()) + .Intersection(Rect::MakeSize(Size(1, 1))); + FML_DCHECK(uvs.has_value()); + if (uvs.has_value()) { + blur_uvs[0] = uvs->GetLeftTop(); + blur_uvs[1] = uvs->GetRightTop(); + blur_uvs[2] = uvs->GetLeftBottom(); + blur_uvs[3] = uvs->GetRightBottom(); + } + } + return blur_uvs; +} + +Scalar CeilToDivisible(Scalar val, Scalar divisor) { + if (divisor == 0.0f) { + return val; + } + + Scalar remainder = fmod(val, divisor); + if (remainder != 0.0f) { + return val + (divisor - remainder); + } else { + return val; + } +} + +Scalar FloorToDivisible(Scalar val, Scalar divisor) { + if (divisor == 0.0f) { + return val; + } + + Scalar remainder = fmod(val, divisor); + if (remainder != 0.0f) { + return val - remainder; + } else { + return val; + } +} + struct DownsamplePassArgs { /// The output size of the down-sampling pass. ISize subpass_size; @@ -166,13 +224,19 @@ struct DownsamplePassArgs { /// This isn't usually exactly as we'd calculate because it has to be rounded /// to integer boundaries for generating the texture for the output. Vector2 effective_scalar; + /// Transforms from unrotated local space to position the output from the + /// down-sample pass. + /// This can differ if we request a coverage hint but it is rejected, as is + /// the case with backdrop filters. + Matrix transform; }; /// Calculates info required for the down-sampling pass. DownsamplePassArgs CalculateDownsamplePassArgs( Vector2 scaled_sigma, Vector2 padding, - ISize input_snapshot_size, + const Snapshot& input_snapshot, + const std::optional& source_expanded_coverage_hint, const std::shared_ptr& input, const Entity& snapshot_entity) { Scalar desired_scalar = @@ -182,8 +246,6 @@ DownsamplePassArgs CalculateDownsamplePassArgs( // gutter from the expanded_coverage_hint, we can skip the downsample pass. // pass. Vector2 downsample_scalar(desired_scalar, desired_scalar); - Rect source_rect = Rect::MakeSize(input_snapshot_size); - Rect source_rect_padded = source_rect.Expand(padding); // TODO(gaaclarke): The padding could be removed if we know it's not needed or // resized to account for the expanded_clip_coverage. There doesn't appear // to be the math to make those calculations though. The following @@ -192,19 +254,68 @@ DownsamplePassArgs CalculateDownsamplePassArgs( // // !input_snapshot->GetCoverage()->Expand(-local_padding) // .Contains(coverage_hint.value())) - Vector2 downsampled_size = source_rect_padded.GetSize() * downsample_scalar; - ISize subpass_size = - ISize(round(downsampled_size.x), round(downsampled_size.y)); - Vector2 effective_scalar = - Vector2(subpass_size) / source_rect_padded.GetSize(); - - Quad uvs = GaussianBlurFilterContents::CalculateUVs( - input, snapshot_entity, source_rect_padded, input_snapshot_size); - return { - .subpass_size = subpass_size, - .uvs = uvs, - .effective_scalar = effective_scalar, - }; + + std::optional snapshot_coverage = input_snapshot.GetCoverage(); + if (input_snapshot.transform.IsIdentity() && + source_expanded_coverage_hint.has_value() && + snapshot_coverage.has_value() && + snapshot_coverage->Contains(source_expanded_coverage_hint.value())) { + // If the snapshot's transform is the identity transform and we have + // coverage hint that fits inside of the snapshots coverage that means the + // coverage hint was ignored so we will trim out the area we are interested + // in the down-sample pass. This usually means we have a backdrop image + // filter. + // + // The region we cut out will be aligned with the down-sample divisor to + // avoid pixel alignment problems that create shimmering. + int32_t divisor = std::round(1.0f / desired_scalar); + Rect aligned_coverage_hint = Rect::MakeLTRB( + FloorToDivisible(source_expanded_coverage_hint->GetLeft(), divisor), + FloorToDivisible(source_expanded_coverage_hint->GetTop(), divisor), + source_expanded_coverage_hint->GetRight(), + source_expanded_coverage_hint->GetBottom()); + aligned_coverage_hint = Rect::MakeXYWH( + aligned_coverage_hint.GetX(), aligned_coverage_hint.GetY(), + CeilToDivisible(aligned_coverage_hint.GetWidth(), divisor), + CeilToDivisible(aligned_coverage_hint.GetHeight(), divisor)); + ISize source_size = ISize(aligned_coverage_hint.GetSize().width, + aligned_coverage_hint.GetSize().height); + Vector2 downsampled_size = source_size * downsample_scalar; + Scalar int_part; + FML_DCHECK(std::modf(downsampled_size.x, &int_part) == 0.0f); + FML_DCHECK(std::modf(downsampled_size.y, &int_part) == 0.0f); + (void)int_part; + ISize subpass_size = ISize(downsampled_size.x, downsampled_size.y); + Vector2 effective_scalar = Vector2(subpass_size) / source_size; + FML_DCHECK(effective_scalar == downsample_scalar); + + Quad uvs = CalculateSnapshotUVs(input_snapshot, aligned_coverage_hint); + return { + .subpass_size = subpass_size, + .uvs = uvs, + .effective_scalar = effective_scalar, + .transform = Matrix::MakeTranslation( + {aligned_coverage_hint.GetX(), aligned_coverage_hint.GetY(), 0})}; + } else { + ////////////////////////////////////////////////////////////////////////////// + auto input_snapshot_size = input_snapshot.texture->GetSize(); + Rect source_rect = Rect::MakeSize(input_snapshot_size); + Rect source_rect_padded = source_rect.Expand(padding); + Vector2 downsampled_size = source_rect_padded.GetSize() * downsample_scalar; + ISize subpass_size = + ISize(round(downsampled_size.x), round(downsampled_size.y)); + Vector2 effective_scalar = + Vector2(subpass_size) / source_rect_padded.GetSize(); + Quad uvs = GaussianBlurFilterContents::CalculateUVs( + input, snapshot_entity, source_rect_padded, input_snapshot_size); + return { + .subpass_size = subpass_size, + .uvs = uvs, + .effective_scalar = effective_scalar, + .transform = + input_snapshot.transform * Matrix::MakeTranslation(-padding), + }; + } } /// Makes a subpass that will render the scaled down input and add the @@ -326,38 +437,6 @@ fml::StatusOr MakeBlurSubpass( } } -/// Returns `rect` relative to `reference`, where Rect::MakeXYWH(0,0,1,1) will -/// be returned when `rect` == `reference`. -Rect MakeReferenceUVs(const Rect& reference, const Rect& rect) { - Rect result = Rect::MakeOriginSize(rect.GetOrigin() - reference.GetOrigin(), - rect.GetSize()); - return result.Scale(1.0f / Vector2(reference.GetSize())); -} - -Quad CalculateBlurUVs( - const Snapshot& input_snapshot, - const std::optional& source_expanded_coverage_hint) { - std::optional input_snapshot_coverage = input_snapshot.GetCoverage(); - Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)}; - FML_DCHECK(input_snapshot.transform.IsTranslationScaleOnly()); - if (source_expanded_coverage_hint.has_value() && - input_snapshot_coverage.has_value()) { - // Only process the uvs where the blur is happening, not the whole texture. - std::optional uvs = - MakeReferenceUVs(input_snapshot_coverage.value(), - source_expanded_coverage_hint.value()) - .Intersection(Rect::MakeSize(Size(1, 1))); - FML_DCHECK(uvs.has_value()); - if (uvs.has_value()) { - blur_uvs[0] = uvs->GetLeftTop(); - blur_uvs[1] = uvs->GetRightTop(); - blur_uvs[2] = uvs->GetLeftBottom(); - blur_uvs[3] = uvs->GetRightBottom(); - } - } - return blur_uvs; -} - int ScaleBlurRadius(Scalar radius, Scalar scalar) { return static_cast(std::round(radius * scalar)); } @@ -597,8 +676,8 @@ std::optional GaussianBlurFilterContents::RenderFilter( } DownsamplePassArgs downsample_pass_args = CalculateDownsamplePassArgs( - blur_info.scaled_sigma, blur_info.padding, - input_snapshot->texture->GetSize(), inputs[0], snapshot_entity); + blur_info.scaled_sigma, blur_info.padding, input_snapshot.value(), + source_expanded_coverage_hint, inputs[0], snapshot_entity); fml::StatusOr pass1_out = MakeDownsampleSubpass( renderer, command_buffer, input_snapshot->texture, @@ -611,8 +690,7 @@ std::optional GaussianBlurFilterContents::RenderFilter( Vector2 pass1_pixel_size = 1.0 / Vector2(pass1_out.value().GetRenderTargetTexture()->GetSize()); - Quad blur_uvs = - CalculateBlurUVs(input_snapshot.value(), source_expanded_coverage_hint); + Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)}; fml::StatusOr pass2_out = MakeBlurSubpass( renderer, command_buffer, /*input_pass=*/pass1_out.value(), @@ -676,8 +754,7 @@ std::optional GaussianBlurFilterContents::RenderFilter( .transform = entity.GetTransform() * // Matrix::MakeScale(1.f / blur_info.source_space_scalar) * // - input_snapshot->transform * // - Matrix::MakeTranslation(-blur_info.padding) * // + downsample_pass_args.transform * // Matrix::MakeScale(1 / downsample_pass_args.effective_scalar), .sampler_descriptor = sampler_desc, .opacity = input_snapshot->opacity}, From 1742301c809a44f704eb16e32115c86e195ec3ac Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Wed, 26 Jun 2024 15:10:18 -0700 Subject: [PATCH 46/88] Return a null image from ImageExternalTextureGL::CreateEGLImage if an EGL display is not available (#53594) Previously CreateEGLImage had been failing an assertion if an EGL display is not active on the calling thread. CreateEGLImage should not assert here because it could be called from a deferred task that runs after the raster thread has lost its EGL state. See https://github.com/flutter/flutter/issues/149396 --- shell/platform/android/image_external_texture_gl.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shell/platform/android/image_external_texture_gl.cc b/shell/platform/android/image_external_texture_gl.cc index 92743654d0289..88792d73d812e 100644 --- a/shell/platform/android/image_external_texture_gl.cc +++ b/shell/platform/android/image_external_texture_gl.cc @@ -87,7 +87,11 @@ impeller::UniqueEGLImageKHR ImageExternalTextureGL::CreateEGLImage( } EGLDisplay display = eglGetCurrentDisplay(); - FML_CHECK(display != EGL_NO_DISPLAY); + if (display == EGL_NO_DISPLAY) { + // This could happen when running in a deferred task that executes after + // the thread has lost its EGL state. + return impeller::UniqueEGLImageKHR(); + } EGLClientBuffer client_buffer = impeller::android::GetProcTable().eglGetNativeClientBufferANDROID( From a9194f0f01f42175eaf82a8132167d9c54b60263 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 18:12:19 -0400 Subject: [PATCH 47/88] Roll Skia from 173ee0af82c9 to 55ada83438cd (3 revisions) (#53596) https://skia.googlesource.com/skia.git/+log/173ee0af82c9..55ada83438cd 2024-06-26 nscobie@google.com Add (CoGS) team ownership to Android.bp's CtsSkQPTestCases 2024-06-26 bungeman@google.com Roll gn 2024-06-26 lehoangquyen@google.com GraphiteDawn: increase number of cached UBO bindgroups If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 563f6ac7305f4..ec5d5119eeb0b 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '173ee0af82c961dd36f1a5255c3da59161e0590b', + 'skia_revision': '55ada83438cd1003e15537adb4e12d22070c2a8d', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 2506b6bbc6bc1..af65794d4d7dd 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: ac498059c15e926631a2d448d5117daf +Signature: 871fbab234f6321e42881caaa47485d3 ==================================================================================================== LIBRARY: etc1 From 6d87069e6359cbb7a5e09d0d346737393488d276 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 19:44:03 -0400 Subject: [PATCH 48/88] Roll Skia from 55ada83438cd to 001694095f1b (3 revisions) (#53598) https://skia.googlesource.com/skia.git/+log/55ada83438cd..001694095f1b 2024-06-26 bungeman@google.com [cmake] Enable OBJC and OBJCXX 2024-06-26 jamesgk@google.com [graphite] Support running on Dawn compat 2024-06-26 egdaniel@google.com Fix clock granularity on GraphitePurgeNotUsedSinceResourcesTest. If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index ec5d5119eeb0b..0f1adb524122e 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '55ada83438cd1003e15537adb4e12d22070c2a8d', + 'skia_revision': '001694095f1b5afafcb5fc793b179dd19a958de0', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index af65794d4d7dd..05c6d6fded5f3 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 871fbab234f6321e42881caaa47485d3 +Signature: 51431576124791d752dd975195571f39 ==================================================================================================== LIBRARY: etc1 From 18e1520b30d4aff9e7dfb09eec21c3c4de081ec8 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 20:15:09 -0400 Subject: [PATCH 49/88] Roll Dart SDK from c01f907d34d8 to 8dd486ebfab4 (1 revision) (#53599) https://dart.googlesource.com/sdk.git/+log/c01f907d34d8..8dd486ebfab4 2024-06-26 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-305.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- sky/packages/sky_engine/LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 0f1adb524122e..c74de5b8d7f4c 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'c01f907d34d88fd133cbb1636e76c3cd57505eba', + 'dart_revision': '8dd486ebfab484200b481ee171ca3d713c1019dd', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index d7c34b5d83416..df5c14e8b901f 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/c01f907d34d88fd133cbb1636e76c3cd57505eba +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/8dd486ebfab484200b481ee171ca3d713c1019dd /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From e1e16e9dd09d7201b17c3081d632190515144c6d Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Wed, 26 Jun 2024 23:50:24 -0400 Subject: [PATCH 50/88] Roll Fuchsia Linux SDK from n2dgSmMCaCO7ujvmr... to gBWzGuicxu76K82lg... (#53601) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/fuchsia-linux-sdk-flutter-engine Please CC jimgraham@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_fuchsia | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/DEPS b/DEPS index c74de5b8d7f4c..3fb722e99d8f7 100644 --- a/DEPS +++ b/DEPS @@ -969,7 +969,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/sdk/core/linux-amd64', - 'version': 'n2dgSmMCaCO7ujvmrHIPlsgMLgz3zcicHJUi7-7_zgkC' + 'version': 'gBWzGuicxu76K82lgv4GlyIQgzT4_cL5amo3g4mbDqsC' } ], 'condition': 'download_fuchsia_deps and not download_fuchsia_sdk', diff --git a/ci/licenses_golden/licenses_fuchsia b/ci/licenses_golden/licenses_fuchsia index 5829845345963..e0ad27fa38be0 100644 --- a/ci/licenses_golden/licenses_fuchsia +++ b/ci/licenses_golden/licenses_fuchsia @@ -1,4 +1,4 @@ -Signature: a4b111728b0d148c1fac1b95d99eb2ff +Signature: d6e7bea50a46dc07269b7728a08ef2d8 ==================================================================================================== LIBRARY: fuchsia_sdk @@ -14449,7 +14449,6 @@ ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.audio/plug.fidl + ../.. ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.audio/ring_buffer_format.fidl + ../../../fuchsia/sdk/linux/LICENSE ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.gpioimpl/gpio-impl.fidl + ../../../fuchsia/sdk/linux/LICENSE ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.i2cimpl/i2cimpl.fidl + ../../../fuchsia/sdk/linux/LICENSE -ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.network/history.fidl + ../../../fuchsia/sdk/linux/LICENSE ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.power/config.fidl + ../../../fuchsia/sdk/linux/LICENSE ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.sdmmc/metadata.fidl + ../../../fuchsia/sdk/linux/LICENSE ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.sdmmc/sdmmc.fidl + ../../../fuchsia/sdk/linux/LICENSE @@ -14555,7 +14554,6 @@ FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.audio/plug.fidl FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.audio/ring_buffer_format.fidl FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.gpioimpl/gpio-impl.fidl FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.i2cimpl/i2cimpl.fidl -FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.network/history.fidl FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.power/config.fidl FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.sdmmc/metadata.fidl FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.sdmmc/sdmmc.fidl From 9999c69112177227836baa89529e18e0cf8cacda Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 00:29:07 -0400 Subject: [PATCH 51/88] Roll Dart SDK from 8dd486ebfab4 to d825219c0ce1 (1 revision) (#53602) https://dart.googlesource.com/sdk.git/+log/8dd486ebfab4..d825219c0ce1 2024-06-27 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-306.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_dart | 4 ++-- sky/packages/sky_engine/LICENSE | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DEPS b/DEPS index 3fb722e99d8f7..ba9e3a69bc789 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '8dd486ebfab484200b481ee171ca3d713c1019dd', + 'dart_revision': 'd825219c0ce13d41068ad1844315e88d8c6d3b6a', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index 1f505c82bbc57..d8272eb636665 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: 960100a262e744ffa698f14b7fe97776 +Signature: 18860faf6395d06623f8675ec6ea7e1c ==================================================================================================== LIBRARY: dart @@ -4751,7 +4751,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/c01f907d34d88fd133cbb1636e76c3cd57505eba +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/d825219c0ce13d41068ad1844315e88d8c6d3b6a /third_party/fallback_root_certificates/ ==================================================================================================== diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index df5c14e8b901f..85cfaa1975198 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/8dd486ebfab484200b481ee171ca3d713c1019dd +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/d825219c0ce13d41068ad1844315e88d8c6d3b6a /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From eb70f5245a7f301ac67d98f4800a64d2771591fb Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 00:44:54 -0400 Subject: [PATCH 52/88] Roll Skia from 001694095f1b to 7b55cb1afe40 (1 revision) (#53603) https://skia.googlesource.com/skia.git/+log/001694095f1b..7b55cb1afe40 2024-06-27 kjlubick@google.com Skip wacky_yuv_formats_cubic on Wembley devices If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index ba9e3a69bc789..e95dcbc76a765 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '001694095f1b5afafcb5fc793b179dd19a958de0', + 'skia_revision': '7b55cb1afe4046c763e891efa3b27f27a8195952', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 8f64ea090613f847405adbacc0fe860866c670e9 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 01:59:33 -0400 Subject: [PATCH 53/88] Roll Skia from 7b55cb1afe40 to e2f68b30ea63 (1 revision) (#53605) https://skia.googlesource.com/skia.git/+log/7b55cb1afe40..e2f68b30ea63 2024-06-27 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Dawn from fa24f1553bec to cd996ffba12a (18 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index e95dcbc76a765..55353f2898822 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '7b55cb1afe4046c763e891efa3b27f27a8195952', + 'skia_revision': 'e2f68b30ea63c7cd2809305792d58880cce70bb3', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 7099a99ad036d344679064e97a715e89d9cd99e0 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 03:11:25 -0400 Subject: [PATCH 54/88] Roll Skia from e2f68b30ea63 to fb1458ac7bfd (1 revision) (#53606) https://skia.googlesource.com/skia.git/+log/e2f68b30ea63..fb1458ac7bfd 2024-06-27 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Skia Infra from 72fd79ddaace to 79660091faba (2 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 55353f2898822..0d651fa48895b 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'e2f68b30ea63c7cd2809305792d58880cce70bb3', + 'skia_revision': 'fb1458ac7bfd37f0f888c4b91320e2bbed9010a1', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 05c6d6fded5f3..b02638d2c5415 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 51431576124791d752dd975195571f39 +Signature: 7729f03ff561add7eb8d76a7810e2e47 ==================================================================================================== LIBRARY: etc1 From f63b36bfc66cd7c9f2d5fb75ebbcbe55b05e4299 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 04:32:03 -0400 Subject: [PATCH 55/88] Roll Skia from fb1458ac7bfd to a407ec8a29b9 (2 revisions) (#53607) https://skia.googlesource.com/skia.git/+log/fb1458ac7bfd..a407ec8a29b9 2024-06-27 skia-autoroll@skia-public.iam.gserviceaccount.com Roll ANGLE from 046327343595 to 46dd6457f4bf (10 revisions) 2024-06-27 skia-autoroll@skia-public.iam.gserviceaccount.com Roll vulkan-deps from 782b625ca1dc to 7ff358e64e2b (1 revision) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 0d651fa48895b..4b059cbe18190 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'fb1458ac7bfd37f0f888c4b91320e2bbed9010a1', + 'skia_revision': 'a407ec8a29b9023f5e64f6db2b13ff5f450c515c', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From e41a8c22db3c1817ce8ed04663ed1e185a78e3aa Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 04:38:14 -0400 Subject: [PATCH 56/88] Roll Dart SDK from d825219c0ce1 to 7d7fbb30e0ca (1 revision) (#53608) https://dart.googlesource.com/sdk.git/+log/d825219c0ce1..7d7fbb30e0ca 2024-06-27 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-307.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_dart | 4 ++-- sky/packages/sky_engine/LICENSE | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DEPS b/DEPS index 4b059cbe18190..bca59e252f37b 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'd825219c0ce13d41068ad1844315e88d8c6d3b6a', + 'dart_revision': '7d7fbb30e0ca19c76800b1ad388fa55d09037e66', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index d8272eb636665..c28558675a11a 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: 18860faf6395d06623f8675ec6ea7e1c +Signature: 1e1675156567a2ad88b6cf158c5eefb6 ==================================================================================================== LIBRARY: dart @@ -4751,7 +4751,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/d825219c0ce13d41068ad1844315e88d8c6d3b6a +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/7d7fbb30e0ca19c76800b1ad388fa55d09037e66 /third_party/fallback_root_certificates/ ==================================================================================================== diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index 85cfaa1975198..72c30158e8aae 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/d825219c0ce13d41068ad1844315e88d8c6d3b6a +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/7d7fbb30e0ca19c76800b1ad388fa55d09037e66 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From b42c80460538882aacc1977c2bcbe1a3182ec000 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 08:48:24 -0400 Subject: [PATCH 57/88] Roll Dart SDK from 7d7fbb30e0ca to 65fa56a24416 (1 revision) (#53609) https://dart.googlesource.com/sdk.git/+log/7d7fbb30e0ca..65fa56a24416 2024-06-27 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-308.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- sky/packages/sky_engine/LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index bca59e252f37b..689b003f266c6 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '7d7fbb30e0ca19c76800b1ad388fa55d09037e66', + 'dart_revision': '65fa56a2441637ed17c570a659f9a276228f8d5a', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index 72c30158e8aae..feddc823f1cf4 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/7d7fbb30e0ca19c76800b1ad388fa55d09037e66 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/65fa56a2441637ed17c570a659f9a276228f8d5a /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From b38516b2a7309060d8e1250f88e10d8d578e303e Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 12:16:53 -0400 Subject: [PATCH 58/88] Roll Skia from a407ec8a29b9 to 09a46ebe4c01 (1 revision) (#53610) https://skia.googlesource.com/skia.git/+log/a407ec8a29b9..09a46ebe4c01 2024-06-27 robertphillips@google.com [graphite] Move PrecompileImageFilter to public API If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 689b003f266c6..db1a65fb4036a 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'a407ec8a29b9023f5e64f6db2b13ff5f450c515c', + 'skia_revision': '09a46ebe4c010827a2fafaa7f71f8b0f551240d6', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index b02638d2c5415..9744e89b88e9d 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 7729f03ff561add7eb8d76a7810e2e47 +Signature: 3e3c03bd16c62ad264c86aa8b26105df ==================================================================================================== LIBRARY: etc1 @@ -9516,6 +9516,7 @@ ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/Precom ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileBase.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileBlender.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileColorFilter.h + ../../../flutter/third_party/skia/LICENSE +ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileImageFilter.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileMaskFilter.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileShader.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/modules/skshaper/include/SkShaper_coretext.h + ../../../flutter/third_party/skia/LICENSE @@ -9564,6 +9565,8 @@ ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/Precompile ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileBlenderPriv.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileColorFilter.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileColorFiltersPriv.h + ../../../flutter/third_party/skia/LICENSE +ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileImageFilter.cpp + ../../../flutter/third_party/skia/LICENSE +ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileImageFilterPriv.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileMaskFilter.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShader.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShaderPriv.h + ../../../flutter/third_party/skia/LICENSE @@ -9605,6 +9608,7 @@ FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/Precompi FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileBase.h FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileBlender.h FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileColorFilter.h +FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileImageFilter.h FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileMaskFilter.h FILE: ../../../flutter/third_party/skia/include/gpu/graphite/precompile/PrecompileShader.h FILE: ../../../flutter/third_party/skia/modules/skshaper/include/SkShaper_coretext.h @@ -9653,6 +9657,8 @@ FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileBl FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileBlenderPriv.h FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileColorFilter.cpp FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileColorFiltersPriv.h +FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileImageFilter.cpp +FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileImageFilterPriv.h FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileMaskFilter.cpp FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShader.cpp FILE: ../../../flutter/third_party/skia/src/gpu/graphite/precompile/PrecompileShaderPriv.h From a9172f3d9e8500cff1e55f01c2f40f3e3ed3126b Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 12:58:18 -0400 Subject: [PATCH 59/88] Roll Dart SDK from 65fa56a24416 to b5f079c2936e (1 revision) (#53611) https://dart.googlesource.com/sdk.git/+log/65fa56a24416..b5f079c2936e 2024-06-27 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-309.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- sky/packages/sky_engine/LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index db1a65fb4036a..67616981d2843 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '65fa56a2441637ed17c570a659f9a276228f8d5a', + 'dart_revision': 'b5f079c2936e9ac5f20d17f03cd78fafec1604f8', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index feddc823f1cf4..2d5d2dbb8b2f1 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31865,7 +31865,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/65fa56a2441637ed17c570a659f9a276228f8d5a +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/b5f079c2936e9ac5f20d17f03cd78fafec1604f8 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From d1506c12808ec42e1b277376c4c2b1bd4ec20ac7 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 14:21:12 -0400 Subject: [PATCH 60/88] Roll Skia from 09a46ebe4c01 to dee7339d0b53 (5 revisions) (#53612) https://skia.googlesource.com/skia.git/+log/09a46ebe4c01..dee7339d0b53 2024-06-27 michaelludwig@google.com [graphite] Remove stray vertex attribute declaration 2024-06-27 jvanverth@google.com Disable more wacky_yuv GMs on Wembley. 2024-06-27 nathanasanchez@google.com [Graphite] Make gradient buffer support more defined 2024-06-27 skia-autoroll@skia-public.iam.gserviceaccount.com Manual roll Dawn from cd996ffba12a to 0a3b1b98cce7 (6 revisions) 2024-06-27 skia-autoroll@skia-public.iam.gserviceaccount.com Roll SK Tool from 79660091faba to c3324a905ed2 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 67616981d2843..c947ae67da3e4 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '09a46ebe4c010827a2fafaa7f71f8b0f551240d6', + 'skia_revision': 'dee7339d0b53639059a295ab67a804a1a2e2a735', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 9744e89b88e9d..931854d359c72 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 3e3c03bd16c62ad264c86aa8b26105df +Signature: 94779da786a91d03393573a878c5ad28 ==================================================================================================== LIBRARY: etc1 From 3f40c68757ecf437f561d3fac7dc9d83b7cc8e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Bertheussen?= Date: Thu, 27 Jun 2024 20:44:04 +0200 Subject: [PATCH 61/88] Fix AccessibilityFeatures.disableAnimations flag on Android 12+ (#53428) This PR fixes the problem where Flutter would not respect the "remove animation" accessibility setting on Android 12+. Please see this issue for details: https://github.com/flutter/flutter/issues/130976 As [mentioned](https://github.com/flutter/flutter/issues/130976#issuecomment-1931388665) by [horsemankukka](https://github.com/horsemankukka), the problem has to do with reading `Settings.Global.TRANSITION_ANIMATION_SCALE` as a string instead of a float. Flutter would compare it to the string "0" to determine if animations should be disabled. Presumably, this worked because the settings app did indeed use the string "0" or "1" for this setting. But as of Android 12 it's instead written using float representation ("0.0" or "1.0"), at least on Samsung devices. [The documentation](https://developer.android.com/reference/android/provider/Settings.Global#TRANSITION_ANIMATION_SCALE) also states that this setting should be read as a float, which is what this PR does. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- .../io/flutter/view/AccessibilityBridge.java | 18 +++-- .../flutter/view/AccessibilityBridgeTest.java | 67 +++++++++++++++++++ 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/shell/platform/android/io/flutter/view/AccessibilityBridge.java b/shell/platform/android/io/flutter/view/AccessibilityBridge.java index e6014f4329ca5..8516d62220664 100644 --- a/shell/platform/android/io/flutter/view/AccessibilityBridge.java +++ b/shell/platform/android/io/flutter/view/AccessibilityBridge.java @@ -126,6 +126,12 @@ public class AccessibilityBridge extends AccessibilityNodeProvider { // Font weight adjustment for bold text. FontWeight.Bold - FontWeight.Normal = w700 - w400 = 300. private static final int BOLD_TEXT_WEIGHT_ADJUSTMENT = 300; + // Default transition animation scale (animations enabled) + private static final float DEFAULT_TRANSITION_ANIMATION_SCALE = 1.0f; + + // Transition animation scale when animations are disabled + private static final float DISABLED_TRANSITION_ANIMATION_SCALE = 0.0f; + /// Value is derived from ACTION_TYPE_MASK in AccessibilityNodeInfo.java private static int FIRST_RESOURCE_ID = 267386881; @@ -399,11 +405,13 @@ public void onChange(boolean selfChange, Uri uri) { return; } // Retrieve the current value of TRANSITION_ANIMATION_SCALE from the OS. - String value = - Settings.Global.getString( - contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE); + float value = + Settings.Global.getFloat( + contentResolver, + Settings.Global.TRANSITION_ANIMATION_SCALE, + DEFAULT_TRANSITION_ANIMATION_SCALE); - boolean shouldAnimationsBeDisabled = value != null && value.equals("0"); + boolean shouldAnimationsBeDisabled = value == DISABLED_TRANSITION_ANIMATION_SCALE; if (shouldAnimationsBeDisabled) { accessibilityFeatureFlags |= AccessibilityFeature.DISABLE_ANIMATIONS.value; } else { @@ -560,7 +568,7 @@ private void setBoldTextFlag() { if (shouldBold) { accessibilityFeatureFlags |= AccessibilityFeature.BOLD_TEXT.value; } else { - accessibilityFeatureFlags &= AccessibilityFeature.BOLD_TEXT.value; + accessibilityFeatureFlags &= ~AccessibilityFeature.BOLD_TEXT.value; } sendLatestAccessibilityFlagsToFlutter(); } diff --git a/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java b/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java index 389c329f96c45..f86ea7a3b8d79 100644 --- a/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java +++ b/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java @@ -13,6 +13,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -28,8 +29,10 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.database.ContentObserver; import android.graphics.Rect; import android.os.Bundle; +import android.provider.Settings; import android.text.SpannableString; import android.text.SpannedString; import android.text.style.LocaleSpan; @@ -1346,6 +1349,31 @@ public void itSetsBoldTextFlagCorrectly() { /*platformViewsAccessibilityDelegate=*/ null); verify(mockChannel).setAccessibilityFeatures(1 << 3); + reset(mockChannel); + + // Now verify that clearing the BOLD_TEXT flag doesn't touch any of the other flags. + // Ensure the DISABLE_ANIMATION flag will be set + Settings.Global.putFloat(null, "transition_animation_scale", 0.0f); + // Ensure the BOLD_TEXT flag will be cleared + config.fontWeightAdjustment = 0; + + accessibilityBridge = + setUpBridge( + /*rootAccessibilityView=*/ mockRootView, + /*accessibilityChannel=*/ mockChannel, + /*accessibilityManager=*/ mockManager, + /*contentResolver=*/ null, + /*accessibilityViewEmbedder=*/ mockViewEmbedder, + /*platformViewsAccessibilityDelegate=*/ null); + + // setAccessibilityFeatures() will be called multiple times from AccessibilityBridge's + // constructor, verify that the latest argument is correct + ArgumentCaptor captor = ArgumentCaptor.forClass(Integer.class); + verify(mockChannel, atLeastOnce()).setAccessibilityFeatures(captor.capture()); + assertEquals(1 << 2 /* DISABLE_ANIMATION */, captor.getValue().intValue()); + + // Set back to default + Settings.Global.putFloat(null, "transition_animation_scale", 1.0f); } @Test @@ -2012,6 +2040,45 @@ public void itProducesPlatformViewNodeForVirtualDisplay() { verify(accessibilityViewEmbedder).getRootNode(eq(embeddedView), eq(0), any(Rect.class)); } + @Test + public void testItSetsDisableAnimationsFlagBasedOnTransitionAnimationScale() { + AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); + ContentResolver mockContentResolver = mock(ContentResolver.class); + + AccessibilityBridge accessibilityBridge = + setUpBridge( + /*rootAccessibilityView=*/ null, + /*accessibilityChannel=*/ mockChannel, + /*accessibilityManager=*/ null, + /*contentResolver=*/ mockContentResolver, + /*accessibilityViewEmbedder=*/ null, + /*platformViewsAccessibilityDelegate=*/ null); + + // Capture the observer registered for Settings.Global.TRANSITION_ANIMATION_SCALE + ArgumentCaptor observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); + verify(mockContentResolver) + .registerContentObserver( + eq(Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE)), + eq(false), + observerCaptor.capture()); + ContentObserver observer = observerCaptor.getValue(); + + // Initial state + verify(mockChannel).setAccessibilityFeatures(0); + reset(mockChannel); + + // Animations are disabled + Settings.Global.putFloat(mockContentResolver, "transition_animation_scale", 0.0f); + observer.onChange(false); + verify(mockChannel).setAccessibilityFeatures(1 << 2); + reset(mockChannel); + + // Animations are enabled + Settings.Global.putFloat(mockContentResolver, "transition_animation_scale", 1.0f); + observer.onChange(false); + verify(mockChannel).setAccessibilityFeatures(0); + } + @Test public void releaseDropsChannelMessageHandler() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); From 7ccef46a81860a2c19506995b64061742b3ed88e Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 15:42:32 -0400 Subject: [PATCH 62/88] Roll Skia from dee7339d0b53 to c73e514838b4 (7 revisions) (#53613) https://skia.googlesource.com/skia.git/+log/dee7339d0b53..c73e514838b4 2024-06-27 jvanverth@google.com Disable all wacky_yuv_formats GMs on the Wembleys 2024-06-27 brianosman@google.com Test Graphite in scale-pixels GMs 2024-06-27 jvanverth@google.com [graphite] Add no-swizzle YUV shader. 2024-06-27 bungeman@google.com Use -no-pie insead of -nopie 2024-06-27 bungeman@google.com GN to use compilation_mode dbg for Bazel 2024-06-27 sjong.hwang@samsung.com SkSLTest: Disable SwizzleIndexStore test on Samsung GPU 2024-06-27 nicolettep@google.com [graphite] Hook up YCbCr functionality and enable GM If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index c947ae67da3e4..4f8284ce56d55 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'dee7339d0b53639059a295ab67a804a1a2e2a735', + 'skia_revision': 'c73e514838b4960bae711d6b145b3255403ddeb0', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 931854d359c72..0eda4f5809322 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 94779da786a91d03393573a878c5ad28 +Signature: 48a124927e6dbc7b304b95083164e96f ==================================================================================================== LIBRARY: etc1 From ddd4814b9d407962eee4dc52919e3abddb0c3641 Mon Sep 17 00:00:00 2001 From: Gray Mackall <34871572+gmackall@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:56:47 -0700 Subject: [PATCH 63/88] Re-re-re-land "Upgrade all[most] androidx dependencies to latest" (#53592) Re-re-re-land https://github.com/flutter/engine/pull/53001. I recreated the postsubmit failures of the [roll](https://github.com/flutter/flutter/pull/150733) of the [last land](https://github.com/flutter/engine/pull/53532), and then verified on a local branch that those same postsubmits pass with this upgrade after the land of https://github.com/flutter/flutter/pull/150873. So I have pretty high confidence this won't cause any problems in the framework repo. I also tested on a previous land attempt that the `all_packages` app builds on this branch, so that is also a good sign for the packages repo. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- DEPS | 2 +- shell/platform/android/BUILD.gn | 52 ++-- .../android/FlutterFragmentTest.java | 2 +- testing/scenario_app/android/app/build.gradle | 1 + .../scenario_app/android/app/gradle.lockfile | 228 ------------------ .../android/app/src/main/AndroidManifest.xml | 3 +- testing/scenario_app/android/build.gradle | 4 +- .../android/buildscript-gradle.lockfile | 150 ------------ tools/androidx/files.json | 47 ++-- .../android_embedding_bundle/build.gradle | 2 +- 10 files changed, 58 insertions(+), 433 deletions(-) delete mode 100644 testing/scenario_app/android/app/gradle.lockfile delete mode 100644 testing/scenario_app/android/buildscript-gradle.lockfile diff --git a/DEPS b/DEPS index 4f8284ce56d55..65fb3a4892841 100644 --- a/DEPS +++ b/DEPS @@ -785,7 +785,7 @@ deps = { 'packages': [ { 'package': 'flutter/android/embedding_bundle', - 'version': 'last_updated:2024-06-12T14:15:49-0700' + 'version': 'last_updated:2024-06-18T12:13:41-0700' } ], 'condition': 'download_android_deps', diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index 40e6912ec335f..041e75ee3fdc5 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -353,37 +353,37 @@ android_java_sources = [ ] embedding_dependencies_jars = [ - "//third_party/android_embedding_dependencies/lib/activity-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/annotation-1.2.0.jar", - "//third_party/android_embedding_dependencies/lib/annotation-experimental-1.1.0.jar", - "//third_party/android_embedding_dependencies/lib/annotations-13.0.jar", + "//third_party/android_embedding_dependencies/lib/activity-1.8.1.jar", + "//third_party/android_embedding_dependencies/lib/annotation-jvm-1.8.0.jar", + "//third_party/android_embedding_dependencies/lib/annotation-experimental-1.4.0.jar", + "//third_party/android_embedding_dependencies/lib/annotations-23.0.0.jar", "//third_party/android_embedding_dependencies/lib/collection-1.1.0.jar", - "//third_party/android_embedding_dependencies/lib/core-1.6.0.jar", - "//third_party/android_embedding_dependencies/lib/core-1.8.0.jar", - "//third_party/android_embedding_dependencies/lib/core-common-2.1.0.jar", - "//third_party/android_embedding_dependencies/lib/core-runtime-2.0.0.jar", + "//third_party/android_embedding_dependencies/lib/core-1.13.1.jar", + "//third_party/android_embedding_dependencies/lib/core-1.10.3.jar", + "//third_party/android_embedding_dependencies/lib/core-common-2.2.0.jar", + "//third_party/android_embedding_dependencies/lib/core-runtime-2.2.0.jar", "//third_party/android_embedding_dependencies/lib/customview-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/fragment-1.1.0.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-1.5.31.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-common-1.5.31.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk7-1.5.30.jar", - "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk8-1.5.30.jar", - "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-android-1.5.2.jar", - "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-core-jvm-1.5.2.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-common-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-common-java8-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-2.0.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-core-2.0.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-process-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-runtime-2.2.0.jar", - "//third_party/android_embedding_dependencies/lib/lifecycle-viewmodel-2.1.0.jar", + "//third_party/android_embedding_dependencies/lib/fragment-1.7.1.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-1.8.22.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-common-1.8.22.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk7-1.8.20.jar", + "//third_party/android_embedding_dependencies/lib/kotlin-stdlib-jdk8-1.8.20.jar", + "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-android-1.7.1.jar", + "//third_party/android_embedding_dependencies/lib/kotlinx-coroutines-core-jvm-1.7.1.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-common-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-common-java8-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-livedata-core-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-process-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-runtime-2.7.0.jar", + "//third_party/android_embedding_dependencies/lib/lifecycle-viewmodel-2.7.0.jar", "//third_party/android_embedding_dependencies/lib/loader-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/savedstate-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/tracing-1.0.0.jar", + "//third_party/android_embedding_dependencies/lib/savedstate-1.2.1.jar", + "//third_party/android_embedding_dependencies/lib/tracing-1.2.0.jar", "//third_party/android_embedding_dependencies/lib/versionedparcelable-1.1.1.jar", "//third_party/android_embedding_dependencies/lib/viewpager-1.0.0.jar", - "//third_party/android_embedding_dependencies/lib/window-1.0.0-beta04.jar", - "//third_party/android_embedding_dependencies/lib/window-java-1.0.0-beta04.jar", + "//third_party/android_embedding_dependencies/lib/window-1.2.0.jar", + "//third_party/android_embedding_dependencies/lib/window-java-1.2.0.jar", ] action("check_imports") { diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java index 0c885997b9132..24d7c6ea32a5c 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentTest.java @@ -322,7 +322,7 @@ public void itDelegatesOnBackPressedWithSetFrameworkHandlesBack() { // Calling onBackPressed now will still be handled by Android (the default), // until setFrameworkHandlesBack is set to true. - activity.onBackPressed(); + activity.getOnBackPressedDispatcher().onBackPressed(); verify(mockDelegate, times(0)).onBackPressed(); // Setting setFrameworkHandlesBack to true means the delegate will receive diff --git a/testing/scenario_app/android/app/build.gradle b/testing/scenario_app/android/app/build.gradle index 51eea659614d9..a03b92bdac42f 100644 --- a/testing/scenario_app/android/app/build.gradle +++ b/testing/scenario_app/android/app/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { + namespace = "dev.flutter.scenarios" lintOptions { abortOnError true checkAllWarnings true diff --git a/testing/scenario_app/android/app/gradle.lockfile b/testing/scenario_app/android/app/gradle.lockfile deleted file mode 100644 index f79689a036e99..0000000000000 --- a/testing/scenario_app/android/app/gradle.lockfile +++ /dev/null @@ -1,228 +0,0 @@ -# This is a Gradle generated file for dependency locking. -# Manual edits can break the build and are not advised. -# This file is expected to be part of source control. -androidx.activity:activity:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-experimental:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation:1.0.0=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -androidx.annotation:annotation:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-common:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-runtime:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.asynclayoutinflater:asynclayoutinflater:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cardview:cardview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.concurrent:concurrent-futures:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout-solver:1.1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout:1.1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.coordinatorlayout:coordinatorlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core:1.6.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.drawerlayout:drawerlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.interpolator:interpolator:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-ui:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common:2.3.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-process:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.print:print:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.recyclerview:recyclerview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.slidingpanelayout:slidingpanelayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.swiperefreshlayout:swiperefreshlayout:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test.espresso:espresso-core:3.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -androidx.test.espresso:espresso-idling-resource:3.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -androidx.test.ext:junit:1.1.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test.services:storage:1.4.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test:annotation:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test:core:1.5.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test:monitor:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -androidx.test:monitor:1.6.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.test:rules:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -androidx.test:runner:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.transition:transition:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable-animated:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.window:window-java:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.window:window:1.0.0-beta04=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.android.tools.analytics-library:protos:30.0.0=lintClassPath -com.android.tools.analytics-library:shared:30.0.0=lintClassPath -com.android.tools.analytics-library:tracker:30.0.0=lintClassPath -com.android.tools.build:aapt2-proto:4.1.0-alpha01-6193524=lintClassPath -com.android.tools.build:apksig:7.0.0=lintClassPath -com.android.tools.build:apkzlib:7.0.0=lintClassPath -com.android.tools.build:builder-model:7.0.0=lintClassPath -com.android.tools.build:builder-test-api:7.0.0=lintClassPath -com.android.tools.build:builder:7.0.0=lintClassPath -com.android.tools.build:manifest-merger:30.0.0=lintClassPath -com.android.tools.ddms:ddmlib:30.0.0=lintClassPath -com.android.tools.external.com-intellij:intellij-core:30.0.0=lintClassPath -com.android.tools.external.com-intellij:kotlin-compiler:30.0.0=lintClassPath -com.android.tools.external.org-jetbrains:uast:30.0.0=lintClassPath -com.android.tools.layoutlib:layoutlib-api:30.0.0=lintClassPath -com.android.tools.lint:lint-api:30.0.0=lintClassPath -com.android.tools.lint:lint-checks:30.0.0=lintClassPath -com.android.tools.lint:lint-gradle:30.0.0=lintClassPath -com.android.tools.lint:lint-model:30.0.0=lintClassPath -com.android.tools.lint:lint:30.0.0=lintClassPath -com.android.tools:annotations:30.0.0=lintClassPath -com.android.tools:common:30.0.0=lintClassPath -com.android.tools:dvlib:30.0.0=lintClassPath -com.android.tools:repository:30.0.0=lintClassPath -com.android.tools:sdk-common:30.0.0=lintClassPath -com.android.tools:sdklib:30.0.0=lintClassPath -com.android:signflinger:7.0.0=lintClassPath -com.android:zipflinger:7.0.0=lintClassPath -com.beust:jcommander:1.78=lintClassPath -com.github.javaparser:javaparser-core:3.17.0=lintClassPath -com.google.android.material:material:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.code.findbugs:jsr305:2.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.code.findbugs:jsr305:3.0.2=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata,lintClassPath -com.google.code.gson:gson:2.8.6=lintClassPath -com.google.errorprone:error_prone_annotations:2.3.4=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -com.google.guava:failureaccess:1.0.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -com.google.guava:guava:30.1-android=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.google.guava:guava:30.1-jre=lintClassPath -com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -com.google.j2objc:j2objc-annotations:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -com.google.jimfs:jimfs:1.1=lintClassPath -com.google.protobuf:protobuf-java:3.10.0=lintClassPath -com.googlecode.json-simple:json-simple:1.1=lintClassPath -com.squareup.curtains:curtains:1.0.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-android-core:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-android-instrumentation:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-android-utils:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-object-watcher-android-androidx:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-object-watcher-android-support-fragments:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-object-watcher-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:leakcanary-object-watcher:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:plumber-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark-android:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark-graph:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark-hprof:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark-log:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.leakcanary:shark:2.7=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup.okio:okio:2.2.2=debugAndroidTestRuntimeClasspath -com.squareup:javawriter:2.1.1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -com.squareup:javawriter:2.5.0=lintClassPath -com.sun.activation:javax.activation:1.2.0=lintClassPath -com.sun.istack:istack-commons-runtime:3.0.8=lintClassPath -com.sun.xml.fastinfoset:FastInfoset:1.2.16=lintClassPath -com.thoughtworks.qdox:qdox:1.12.1=lintClassPath -commons-codec:commons-codec:1.10=lintClassPath -commons-io:commons-io:2.4=lintClassPath -commons-logging:commons-logging:1.2=lintClassPath -info.picocli:picocli:4.5.2=lintClassPath -it.unimi.dsi:fastutil:8.4.0=lintClassPath -jakarta.activation:jakarta.activation-api:1.2.1=lintClassPath -jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=lintClassPath -javax.inject:javax.inject:1=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -jline:jline:2.14.6=lintClassPath -junit:junit:4.12=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -junit:junit:4.13.1=lintClassPath -junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -net.java.dev.jna:jna-platform:5.6.0=lintClassPath -net.java.dev.jna:jna:5.6.0=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath -net.sf.jopt-simple:jopt-simple:4.9=lintClassPath -net.sf.kxml:kxml2:2.3.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,lintClassPath -org.apache.ant:ant-antlr:1.10.9=lintClassPath -org.apache.ant:ant-junit:1.10.9=lintClassPath -org.apache.ant:ant-launcher:1.10.9=lintClassPath -org.apache.ant:ant:1.10.9=lintClassPath -org.apache.commons:commons-compress:1.20=lintClassPath -org.apache.httpcomponents:httpclient:4.5.6=lintClassPath -org.apache.httpcomponents:httpcore:4.4.10=lintClassPath -org.apache.httpcomponents:httpmime:4.5.6=lintClassPath -org.bouncycastle:bcpkix-jdk15on:1.56=lintClassPath -org.bouncycastle:bcprov-jdk15on:1.56=lintClassPath -org.checkerframework:checker-compat-qual:2.5.5=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -org.checkerframework:checker-qual:3.5.0=lintClassPath -org.codehaus.groovy:groovy-all:3.0.7=lintClassPath -org.codehaus.groovy:groovy-ant:3.0.7=lintClassPath -org.codehaus.groovy:groovy-astbuilder:3.0.7=lintClassPath -org.codehaus.groovy:groovy-cli-picocli:3.0.7=lintClassPath -org.codehaus.groovy:groovy-console:3.0.7=lintClassPath -org.codehaus.groovy:groovy-datetime:3.0.7=lintClassPath -org.codehaus.groovy:groovy-docgenerator:3.0.7=lintClassPath -org.codehaus.groovy:groovy-groovydoc:3.0.7=lintClassPath -org.codehaus.groovy:groovy-groovysh:3.0.7=lintClassPath -org.codehaus.groovy:groovy-jmx:3.0.7=lintClassPath -org.codehaus.groovy:groovy-json:3.0.7=lintClassPath -org.codehaus.groovy:groovy-jsr223:3.0.7=lintClassPath -org.codehaus.groovy:groovy-macro:3.0.7=lintClassPath -org.codehaus.groovy:groovy-nio:3.0.7=lintClassPath -org.codehaus.groovy:groovy-servlet:3.0.7=lintClassPath -org.codehaus.groovy:groovy-sql:3.0.7=lintClassPath -org.codehaus.groovy:groovy-swing:3.0.7=lintClassPath -org.codehaus.groovy:groovy-templates:3.0.7=lintClassPath -org.codehaus.groovy:groovy-test-junit5:3.0.7=lintClassPath -org.codehaus.groovy:groovy-test:3.0.7=lintClassPath -org.codehaus.groovy:groovy-testng:3.0.7=lintClassPath -org.codehaus.groovy:groovy-xml:3.0.7=lintClassPath -org.codehaus.groovy:groovy:3.0.7=lintClassPath -org.glassfish.jaxb:jaxb-runtime:2.3.2=lintClassPath -org.glassfish.jaxb:txw2:2.3.2=lintClassPath -org.hamcrest:hamcrest-core:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,lintClassPath,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.hamcrest:hamcrest-integration:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -org.hamcrest:hamcrest-library:1.3=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath -org.jacoco:org.jacoco.agent:0.8.8=androidJacocoAnt -org.jacoco:org.jacoco.ant:0.8.8=androidJacocoAnt -org.jacoco:org.jacoco.core:0.8.8=androidJacocoAnt -org.jacoco:org.jacoco.report:0.8.8=androidJacocoAnt -org.jetbrains.intellij.deps:trove4j:1.0.20181211=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath -org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-daemon-embeddable:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.6.10=kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-reflect:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-script-runtime:1.6.10=kotlinCompilerClasspath,kotlinKlibCommonizerClasspath -org.jetbrains.kotlin:kotlin-stdlib-common:1.4.21=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-stdlib-common:1.6.10=apiDependenciesMetadata,debugApiDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,releaseApiDependenciesMetadata -org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10=apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-stdlib:1.4.21=androidTestImplementationDependenciesMetadata,debugAndroidTestImplementationDependenciesMetadata -org.jetbrains.kotlin:kotlin-stdlib:1.4.32=lintClassPath -org.jetbrains.kotlin:kotlin-stdlib:1.6.10=apiDependenciesMetadata,debugApiDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,releaseApiDependenciesMetadata -org.jetbrains.kotlin:kotlin-stdlib:1.7.10=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains:annotations:13.0=androidTestImplementationDependenciesMetadata,apiDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugApiDependenciesMetadata,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,lintClassPath,releaseApiDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.junit.jupiter:junit-jupiter-api:5.7.0=lintClassPath -org.junit.jupiter:junit-jupiter-engine:5.7.0=lintClassPath -org.junit.platform:junit-platform-commons:1.7.0=lintClassPath -org.junit.platform:junit-platform-engine:1.7.0=lintClassPath -org.junit.platform:junit-platform-launcher:1.7.0=lintClassPath -org.junit:junit-bom:5.7.0=lintClassPath -org.jvnet.staxex:stax-ex:1.8.1=lintClassPath -org.opentest4j:opentest4j:1.2.0=lintClassPath -org.ow2.asm:asm-analysis:7.0=lintClassPath -org.ow2.asm:asm-analysis:9.2=androidJacocoAnt -org.ow2.asm:asm-commons:7.0=lintClassPath -org.ow2.asm:asm-commons:9.2=androidJacocoAnt -org.ow2.asm:asm-tree:7.0=lintClassPath -org.ow2.asm:asm-tree:9.2=androidJacocoAnt -org.ow2.asm:asm-util:7.0=lintClassPath -org.ow2.asm:asm:7.0=lintClassPath -org.ow2.asm:asm:9.2=androidJacocoAnt -org.testng:testng:7.3.0=lintClassPath -xerces:xercesImpl:2.12.0=lintClassPath -xml-apis:xml-apis:1.4.01=lintClassPath -empty=androidApis,androidJdkImage,androidTestApiDependenciesMetadata,androidTestCompileOnlyDependenciesMetadata,androidTestDebugApiDependenciesMetadata,androidTestDebugCompileOnlyDependenciesMetadata,androidTestDebugImplementationDependenciesMetadata,androidTestDebugIntransitiveDependenciesMetadata,androidTestDebugRuntimeOnlyDependenciesMetadata,androidTestIntransitiveDependenciesMetadata,androidTestReleaseApiDependenciesMetadata,androidTestReleaseCompileOnlyDependenciesMetadata,androidTestReleaseImplementationDependenciesMetadata,androidTestReleaseIntransitiveDependenciesMetadata,androidTestReleaseRuntimeOnlyDependenciesMetadata,androidTestRuntimeOnlyDependenciesMetadata,androidTestUtil,compileOnlyDependenciesMetadata,coreLibraryDesugaring,debugAndroidTestAnnotationProcessorClasspath,debugAndroidTestApiDependenciesMetadata,debugAndroidTestCompileOnlyDependenciesMetadata,debugAndroidTestIntransitiveDependenciesMetadata,debugAndroidTestRuntimeOnlyDependenciesMetadata,debugAnnotationProcessorClasspath,debugCompileOnly,debugCompileOnlyDependenciesMetadata,debugIntransitiveDependenciesMetadata,debugReverseMetadataValues,debugRuntimeOnlyDependenciesMetadata,debugUnitTestAnnotationProcessorClasspath,debugUnitTestApiDependenciesMetadata,debugUnitTestCompileOnlyDependenciesMetadata,debugUnitTestImplementationDependenciesMetadata,debugUnitTestIntransitiveDependenciesMetadata,debugUnitTestRuntimeOnlyDependenciesMetadata,debugWearBundling,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugAndroidTest,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,kotlinNativeCompilerPluginClasspath,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseCompileOnly,releaseCompileOnlyDependenciesMetadata,releaseIntransitiveDependenciesMetadata,releaseReverseMetadataValues,releaseRuntimeOnlyDependenciesMetadata,releaseUnitTestAnnotationProcessorClasspath,releaseUnitTestApiDependenciesMetadata,releaseUnitTestCompileOnlyDependenciesMetadata,releaseUnitTestImplementationDependenciesMetadata,releaseUnitTestIntransitiveDependenciesMetadata,releaseUnitTestRuntimeOnlyDependenciesMetadata,releaseWearBundling,runtimeOnlyDependenciesMetadata,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testDebugApiDependenciesMetadata,testDebugCompileOnlyDependenciesMetadata,testDebugImplementationDependenciesMetadata,testDebugIntransitiveDependenciesMetadata,testDebugRuntimeOnlyDependenciesMetadata,testFixturesApiDependenciesMetadata,testFixturesCompileOnlyDependenciesMetadata,testFixturesDebugApiDependenciesMetadata,testFixturesDebugCompileOnlyDependenciesMetadata,testFixturesDebugImplementationDependenciesMetadata,testFixturesDebugIntransitiveDependenciesMetadata,testFixturesDebugRuntimeOnlyDependenciesMetadata,testFixturesImplementationDependenciesMetadata,testFixturesIntransitiveDependenciesMetadata,testFixturesReleaseApiDependenciesMetadata,testFixturesReleaseCompileOnlyDependenciesMetadata,testFixturesReleaseImplementationDependenciesMetadata,testFixturesReleaseIntransitiveDependenciesMetadata,testFixturesReleaseRuntimeOnlyDependenciesMetadata,testFixturesRuntimeOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testReleaseApiDependenciesMetadata,testReleaseCompileOnlyDependenciesMetadata,testReleaseImplementationDependenciesMetadata,testReleaseIntransitiveDependenciesMetadata,testReleaseRuntimeOnlyDependenciesMetadata,testRuntimeOnlyDependenciesMetadata diff --git a/testing/scenario_app/android/app/src/main/AndroidManifest.xml b/testing/scenario_app/android/app/src/main/AndroidManifest.xml index e99d9ae8ae6b5..e400c24567a89 100644 --- a/testing/scenario_app/android/app/src/main/AndroidManifest.xml +++ b/testing/scenario_app/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> Date: Thu, 27 Jun 2024 13:07:19 -0700 Subject: [PATCH 64/88] =?UTF-8?q?Fix=20#150515=20Provide=20required=20head?= =?UTF-8?q?ers=20for=20build=20with=20Clang-16=20and=20GCC=20=E2=80=A6=20(?= =?UTF-8?q?#53479)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes Impeller engine build with `clang-16` and GCC 14 C++Stdlib does not implicitly include ``. Fixes issue: #150515 *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- fml/synchronization/sync_switch.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fml/synchronization/sync_switch.cc b/fml/synchronization/sync_switch.cc index 7340086af95b3..2c04fae2f04cf 100644 --- a/fml/synchronization/sync_switch.cc +++ b/fml/synchronization/sync_switch.cc @@ -4,6 +4,8 @@ #include "flutter/fml/synchronization/sync_switch.h" +#include + namespace fml { SyncSwitch::Handlers& SyncSwitch::Handlers::SetIfTrue( From ab22ab50d27781b8ed817875c83ca4335ee74726 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 16:58:09 -0400 Subject: [PATCH 65/88] Roll Skia from c73e514838b4 to cbd6e55139ca (4 revisions) (#53615) https://skia.googlesource.com/skia.git/+log/c73e514838b4..cbd6e55139ca 2024-06-27 jamesgk@google.com [graphite] Don't exceed 128 workgroup invocations in test 2024-06-27 skia-autoroll@skia-public.iam.gserviceaccount.com Roll vulkan-deps from 7ff358e64e2b to 117f1e2fcf1c (7 revisions) 2024-06-27 kjlubick@google.com Extract VulkanMemoryAllocator into its own module 2024-06-27 nicolettep@google.com [graphite] Restore running of certain unit tests If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 49 ++++++++++++++++++++++++++++---- sky/packages/sky_engine/LICENSE | 32 +++++++++++++++++++++ 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/DEPS b/DEPS index 65fb3a4892841..bd2f0d725e62c 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'c73e514838b4960bae711d6b145b3255403ddeb0', + 'skia_revision': 'cbd6e55139cad16a2578c1ca41317a1cc93ae19a', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 0eda4f5809322..bed0ab99a6c34 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 48a124927e6dbc7b304b95083164e96f +Signature: 2cb8da109ec097620f6163f493bc2bbe ==================================================================================================== LIBRARY: etc1 @@ -5124,8 +5124,8 @@ ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/vk/GrVkSamplerYcbcrConv ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/vk/GrVkSamplerYcbcrConversion.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/vk/GrVkTypesPriv.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/vk/GrVkTypesPriv.h + ../../../flutter/third_party/skia/LICENSE -ORIGIN: ../../../flutter/third_party/skia/src/gpu/vk/VulkanAMDMemoryAllocator.cpp + ../../../flutter/third_party/skia/LICENSE -ORIGIN: ../../../flutter/third_party/skia/src/gpu/vk/VulkanAMDMemoryAllocator.h + ../../../flutter/third_party/skia/LICENSE +ORIGIN: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanAMDMemoryAllocator.cpp + ../../../flutter/third_party/skia/LICENSE +ORIGIN: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanAMDMemoryAllocator.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorWrapper.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorWrapper.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/image/SkImage_Lazy.h + ../../../flutter/third_party/skia/LICENSE @@ -5337,8 +5337,8 @@ FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/vk/GrVkSamplerYcbcrConver FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/vk/GrVkSamplerYcbcrConversion.h FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/vk/GrVkTypesPriv.cpp FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/vk/GrVkTypesPriv.h -FILE: ../../../flutter/third_party/skia/src/gpu/vk/VulkanAMDMemoryAllocator.cpp -FILE: ../../../flutter/third_party/skia/src/gpu/vk/VulkanAMDMemoryAllocator.h +FILE: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanAMDMemoryAllocator.cpp +FILE: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanAMDMemoryAllocator.h FILE: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorWrapper.cpp FILE: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorWrapper.h FILE: ../../../flutter/third_party/skia/src/image/SkImage_Lazy.h @@ -9713,6 +9713,43 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== +==================================================================================================== +LIBRARY: skia +ORIGIN: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorPriv.h + ../../../flutter/third_party/skia/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../flutter/third_party/skia/src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorPriv.h +---------------------------------------------------------------------------------------------------- +Copyright 2024 Google LLC. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +==================================================================================================== + ==================================================================================================== LIBRARY: skia ORIGIN: ../../../flutter/third_party/skia/src/ports/SkFontScanner_fontations.cpp + ../../../flutter/third_party/skia/LICENSE @@ -9752,4 +9789,4 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== -Total license count: 70 +Total license count: 71 diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index 2d5d2dbb8b2f1..ad768355216ee 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -28833,6 +28833,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- skia +Copyright 2024 Google LLC. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------------------- +skia + Copyright 2024 The Android Open Source Project Redistribution and use in source and binary forms, with or without From cb855cb149b193b1d2fa9db8961c2f1f54ab4786 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Thu, 27 Jun 2024 14:14:16 -0700 Subject: [PATCH 66/88] Update DEPS to pull in 8c2d66fa4e6298894425f5bdd0591bc5b1154c53. (#53614) --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index bd2f0d725e62c..2089c81172407 100644 --- a/DEPS +++ b/DEPS @@ -277,7 +277,7 @@ allowed_hosts = [ ] deps = { - 'src': 'https://github.com/flutter/buildroot.git' + '@' + '9a4ba8138aed94000ac5070590a21030008903bb', + 'src': 'https://github.com/flutter/buildroot.git' + '@' + '8c2d66fa4e6298894425f5bdd0591bc5b1154c53', 'src/flutter/third_party/depot_tools': Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '580b4ff3f5cd0dcaa2eacda28cefe0f45320e8f7', From f61b59ab76c6a009c70418bdf51becce08829631 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 17:30:12 -0400 Subject: [PATCH 67/88] Roll Dart SDK from b5f079c2936e to e7022f6eb6c9 (1 revision) (#53616) https://dart.googlesource.com/sdk.git/+log/b5f079c2936e..e7022f6eb6c9 2024-06-27 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-310.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- sky/packages/sky_engine/LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 2089c81172407..118ee154f4be7 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'b5f079c2936e9ac5f20d17f03cd78fafec1604f8', + 'dart_revision': 'e7022f6eb6c9ec6ff66f4ca4d6c540a1ed91b01d', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index ad768355216ee..ac6c8cbb79e11 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31897,7 +31897,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/b5f079c2936e9ac5f20d17f03cd78fafec1604f8 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/e7022f6eb6c9ec6ff66f4ca4d6c540a1ed91b01d /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From 94591ffb20dfb4319507397e2354dbb17ab1bbb5 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 18:17:22 -0400 Subject: [PATCH 68/88] Roll Skia from cbd6e55139ca to 1700e3962acd (2 revisions) (#53619) https://skia.googlesource.com/skia.git/+log/cbd6e55139ca..1700e3962acd 2024-06-27 nicolettep@google.com [graphite] Disable MultisampleRetainTest which fails on a task 2024-06-27 brianosman@google.com Always emit stack_rewind stages in SkSL's RP Builder If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 118ee154f4be7..0abc26a6825e4 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'cbd6e55139cad16a2578c1ca41317a1cc93ae19a', + 'skia_revision': '1700e3962acdcc196b8548caec4f0bc83cdd4a9a', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index bed0ab99a6c34..ad0ef2fd3ca28 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 2cb8da109ec097620f6163f493bc2bbe +Signature: 3050d088dea416486ead5defb846dc46 ==================================================================================================== LIBRARY: etc1 From a78f5ce743cef1f03a7cd3b2105f0ddcb94e8c14 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Thu, 27 Jun 2024 21:44:11 -0400 Subject: [PATCH 69/88] Roll Dart SDK from e7022f6eb6c9 to 0820b0766ac9 (1 revision) (#53623) https://dart.googlesource.com/sdk.git/+log/e7022f6eb6c9..0820b0766ac9 2024-06-27 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-311.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 28 ++++++++++++++-------------- ci/licenses_golden/licenses_dart | 4 ++-- sky/packages/sky_engine/LICENSE | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/DEPS b/DEPS index 0abc26a6825e4..a6612ff009e0a 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'e7022f6eb6c9ec6ff66f4ca4d6c540a1ed91b01d', + 'dart_revision': '0820b0766ac9656023394840538fe9ab70d55f0a', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py @@ -72,12 +72,12 @@ vars = { 'dart_protobuf_gn_rev': 'ca669f79945418f6229e4fef89b666b2a88cbb10', 'dart_protobuf_rev': 'ccf104dbc36929c0f8708285d5f3a8fae206343e', 'dart_pub_rev': 'ddc1c2fd2e2a7cd94a0b92ea033961a25f4ad517', - 'dart_tools_rev': 'e660a68dce659311fb47735ab00365e26fca2fe3', - 'dart_watcher_rev': 'c00fc2a6cd869cdebbc52e00af3d912d25745729', + 'dart_tools_rev': '4c606868746da309963589e99b39d2017c582975', + 'dart_watcher_rev': 'f312f1f81c5272ad34ed5c40f29ba8599caed3ef', 'dart_web_rev': '6b8a46561b82de9b20d77d9ac491844d303ca08f', - 'dart_webdev_rev': 'c56611255f3f02642da10750448a8c90a9fa7b47', + 'dart_webdev_rev': '75417c09181c97786d9539a662834bed9d2f1e77', 'dart_webkit_inspection_protocol_rev': '5740cc91eaeb13a02007b77b128fccf4b056db6e', - 'dart_yaml_edit_rev': '08a146ef8f2c7aba908d2017c9ec840b882c9e51', + 'dart_yaml_edit_rev': 'ad3292cd8e893747fae73a7c552d8c858a2be986', 'ocmock_rev': 'c4ec0e3a7a9f56cfdbd0aa01f4f97bb4b75c5ef8', # v3.7.1 @@ -386,7 +386,7 @@ deps = { Var('dart_git') + '/dart_style.git@a6ad7693555a9add6f98ad6fd94de80d35c89415', 'src/flutter/third_party/dart/third_party/pkg/dartdoc': - Var('dart_git') + '/dartdoc.git@88df88c9278ec4ec31df818f3ae33d4f91c8cd64', + Var('dart_git') + '/dartdoc.git@7e5da6090e6a48cebaee8789ca0fc396b34fd8a4', 'src/flutter/third_party/dart/third_party/pkg/file': Var('dart_git') + '/external/github.com/google/file.dart@07cacaed6679a173e29176747e6ce0325742749f', @@ -398,10 +398,10 @@ deps = { Var('dart_git') + '/glob.git@6d3ba5ec02817e62d17ace040590bb81a3e1242f', 'src/flutter/third_party/dart/third_party/pkg/html': - Var('dart_git') + '/html.git@3bc803d7e655491b243418f19300ef0c6112bcea', + Var('dart_git') + '/html.git@f6c2c71dd6dc23bda3b4c5ac1290cf7207748071', 'src/flutter/third_party/dart/third_party/pkg/http': - Var('dart_git') + '/http.git@4d8e7ef73d6135a8cc9b5e53db1beb43977d44b0', + Var('dart_git') + '/http.git@bf96551406600a2ec520a4248ff635bfd268edeb', 'src/flutter/third_party/dart/third_party/pkg/http_multi_server': Var('dart_git') + '/http_multi_server.git@25941e260658efb324de857e6022f418faf9bdd1', @@ -413,7 +413,7 @@ deps = { Var('dart_git') + '/intl.git@5d65e3808ce40e6282e40881492607df4e35669f', 'src/flutter/third_party/dart/third_party/pkg/json_rpc_2': - Var('dart_git') + '/json_rpc_2.git@5b1cbd679756700d5f319bf10a217da53e98ea52', + Var('dart_git') + '/json_rpc_2.git@616937f6d3837e38a2a287653ddaf722de260702', 'src/flutter/third_party/dart/third_party/pkg/leak_tracker': Var('dart_git') + '/leak_tracker.git@f5620600a5ce1c44f65ddaa02001e200b096e14c', @@ -428,10 +428,10 @@ deps = { Var('dart_git') + '/matcher.git@0abd4054c47a923486a6c0c04b5c974ba13ad2da', 'src/flutter/third_party/dart/third_party/pkg/mime': - Var('dart_git') + '/mime.git@4ca2f5edaafe21f462922d34db99486a44bb08b8', + Var('dart_git') + '/mime.git@fd7010b00ca028918cbd90abc347f98b88b2d00f', 'src/flutter/third_party/dart/third_party/pkg/mockito': - Var('dart_git') + '/mockito.git@2302814df66e651b6710311366501523dbee2e11', + Var('dart_git') + '/mockito.git@9deddcfa4b6b6c1ecb3111891c20cc46c115569d', 'src/flutter/third_party/dart/third_party/pkg/native': Var('dart_git') + '/native.git@fef40aebc3cf34654919e8a5785b6c50b3ea445c', @@ -464,7 +464,7 @@ deps = { Var('dart_git') + '/source_maps.git@caa79c2011015759c6cf3299f299f5cccdf8bb61', 'src/flutter/third_party/dart/third_party/pkg/source_span': - Var('dart_git') + '/source_span.git@59a3903521dbf4c38c77df73669e73174a170327', + Var('dart_git') + '/source_span.git@89520f3009e332ce2b6675f71dca166521c36cc4', 'src/flutter/third_party/dart/third_party/pkg/sse': Var('dart_git') + '/sse.git@7dcde164d5bfe707441f206379ef33e7509e2aac', @@ -473,7 +473,7 @@ deps = { Var('dart_git') + '/stack_trace.git@ab09060b82c936c38c04eb49c1154b83f6648349', 'src/flutter/third_party/dart/third_party/pkg/stream_channel': - Var('dart_git') + '/stream_channel.git@b41ff7a25395ace8b23e454e3d1a3459a71306ca', + Var('dart_git') + '/stream_channel.git@dc620d233e0bea618ee22227d4fd487f055b4ead', 'src/flutter/third_party/dart/third_party/pkg/string_scanner': Var('dart_git') + '/string_scanner.git@e1cab8f0538b50f6d7180598752cf5a7e07e74db', @@ -482,7 +482,7 @@ deps = { Var('dart_git') + '/external/github.com/simolus3/tar.git@552a49d7595e444184d4f91e9afd533aa253a31d', 'src/flutter/third_party/dart/third_party/pkg/term_glyph': - Var('dart_git') + '/term_glyph.git@c86e8171ee7e9f6fc8e775e0be755a603dd0b72d', + Var('dart_git') + '/term_glyph.git@6c2a9770e786f83bb1a863c6947dde5dcbebdbd2', 'src/flutter/third_party/dart/third_party/pkg/test': Var('dart_git') + '/test.git@329c6dff4dfcb178ba6c7009cf1c1b9215b317aa', diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index c28558675a11a..2dca21633882c 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: 1e1675156567a2ad88b6cf158c5eefb6 +Signature: 047011981704cb1b5f4371c54ad1fb40 ==================================================================================================== LIBRARY: dart @@ -4751,7 +4751,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/7d7fbb30e0ca19c76800b1ad388fa55d09037e66 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/0820b0766ac9656023394840538fe9ab70d55f0a /third_party/fallback_root_certificates/ ==================================================================================================== diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index ac6c8cbb79e11..9d9af8da25a69 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31897,7 +31897,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/e7022f6eb6c9ec6ff66f4ca4d6c540a1ed91b01d +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/0820b0766ac9656023394840538fe9ab70d55f0a /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From aa9afcd1083f52ddd6bc22ebeb548a35ee3245fe Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Thu, 27 Jun 2024 20:34:23 -0700 Subject: [PATCH 70/88] [DisplayList] Add support for clipOval to leverage Impeller optimization (#53622) Impeller supports `ClipOval` and will detect oval paths and rrects and use that call instead when appropriate. Adding support for `ClipOval` to DisplayList allows that optimization code to be moved up into the recording process. --- display_list/display_list.h | 2 + display_list/display_list_unittests.cc | 424 ++++++++++++++++-- display_list/dl_builder.cc | 61 ++- display_list/dl_builder.h | 8 + display_list/dl_canvas.h | 3 + display_list/dl_op_receiver.h | 1 + display_list/dl_op_records.h | 20 +- display_list/skia/dl_sk_canvas.cc | 6 + display_list/skia/dl_sk_canvas.h | 1 + display_list/skia/dl_sk_dispatcher.cc | 5 + display_list/skia/dl_sk_dispatcher.h | 1 + .../testing/dl_rendering_unittests.cc | 105 +++-- display_list/testing/dl_test_snippets.cc | 40 +- display_list/testing/dl_test_snippets.h | 1 + display_list/utils/dl_matrix_clip_tracker.cc | 18 + display_list/utils/dl_matrix_clip_tracker.h | 4 + display_list/utils/dl_receiver_utils.h | 3 + impeller/display_list/dl_dispatcher.cc | 8 + impeller/display_list/dl_dispatcher.h | 3 + testing/display_list_testing.cc | 8 + testing/display_list_testing.h | 1 + testing/mock_canvas.cc | 17 + testing/mock_canvas.h | 8 + 23 files changed, 675 insertions(+), 73 deletions(-) diff --git a/display_list/display_list.h b/display_list/display_list.h index 35c19ef9d4a0b..bb67c435cc6d7 100644 --- a/display_list/display_list.h +++ b/display_list/display_list.h @@ -98,9 +98,11 @@ namespace flutter { V(TransformReset) \ \ V(ClipIntersectRect) \ + V(ClipIntersectOval) \ V(ClipIntersectRRect) \ V(ClipIntersectPath) \ V(ClipDifferenceRect) \ + V(ClipDifferenceOval) \ V(ClipDifferenceRRect) \ V(ClipDifferencePath) \ \ diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index 635d38af7c8a9..13902b621a241 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -3439,11 +3439,9 @@ TEST_F(DisplayListTest, ImpellerPathPreferenceIsHonored) { }; DisplayListBuilder builder; - builder.DrawPath(SkPath::Rect(SkRect::MakeLTRB(0, 0, 100, 100)), DlPaint()); - builder.ClipPath(SkPath::Rect(SkRect::MakeLTRB(0, 0, 100, 100)), - ClipOp::kIntersect, true); - builder.DrawShadow(SkPath::Rect(SkRect::MakeLTRB(20, 20, 80, 80)), - DlColor::kBlue(), 1.0f, true, 1.0f); + builder.DrawPath(kTestPath1, DlPaint()); + builder.ClipPath(kTestPath1, ClipOp::kIntersect, true); + builder.DrawShadow(kTestPath1, DlColor::kBlue(), 1.0f, true, 1.0f); auto display_list = builder.Build(); { @@ -4332,36 +4330,66 @@ TEST_F(DisplayListTest, DrawDisplayListForwardsBackdropFlag) { #define CLIP_EXPECTOR(name) ClipExpector name(__FILE__, __LINE__) +struct ClipExpectation { + std::variant shape; + bool is_oval; + ClipOp clip_op; + bool is_aa; + + std::string shape_name() { + switch (shape.index()) { + case 0: + return is_oval ? "SkOval" : "SkRect"; + case 1: + return "SkRRect"; + case 2: + return "SkPath"; + default: + return "Unknown"; + } + } +}; + +::std::ostream& operator<<(::std::ostream& os, const ClipExpectation& expect) { + os << "Expectation("; + switch (expect.shape.index()) { + case 0: + os << std::get(expect.shape); + if (expect.is_oval) { + os << " (oval)"; + } + break; + case 1: + os << std::get(expect.shape); + break; + case 2: + os << std::get(expect.shape); + break; + case 3: + os << "Unknown"; + } + os << ", " << expect.clip_op; + os << ", " << expect.is_aa; + os << ")"; + return os; +} + class ClipExpector : public virtual DlOpReceiver, virtual IgnoreAttributeDispatchHelper, virtual IgnoreTransformDispatchHelper, virtual IgnoreDrawDispatchHelper { public: - struct Expectation { - std::variant shape; - ClipOp clip_op; - bool is_aa; - - std::string shape_name() { - switch (shape.index()) { - case 0: - return "SkRect"; - case 1: - return "SkRRect"; - case 2: - return "SkPath"; - default: - return "Unknown"; - } - } - }; - // file and line supplied automatically from CLIP_EXPECTOR macro explicit ClipExpector(const std::string& file, int line) : file_(file), line_(line) {} ~ClipExpector() { // EXPECT_EQ(index_, clip_expectations_.size()) << label(); + while (index_ < clip_expectations_.size()) { + auto expect = clip_expectations_[index_]; + FML_LOG(ERROR) << "leftover clip shape[" << index_ << "] = " << expect; + index_++; + } } ClipExpector& addExpectation(const SkRect& rect, @@ -4369,6 +4397,19 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = rect, + .is_oval = false, + .clip_op = clip_op, + .is_aa = is_aa, + }); + return *this; + } + + ClipExpector& addOvalExpectation(const SkRect& rect, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) { + clip_expectations_.push_back({ + .shape = rect, + .is_oval = true, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4380,6 +4421,7 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = rrect, + .is_oval = false, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4391,6 +4433,7 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = path, + .is_oval = false, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4402,6 +4445,11 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa) override { check(rect, clip_op, is_aa); } + void clipOval(const SkRect& bounds, + DlCanvas::ClipOp clip_op, + bool is_aa) override { + check(bounds, clip_op, is_aa, true); + } void clipRRect(const SkRRect& rrect, DlCanvas::ClipOp clip_op, bool is_aa) override { @@ -4415,22 +4463,23 @@ class ClipExpector : public virtual DlOpReceiver, private: size_t index_ = 0; - std::vector clip_expectations_; + std::vector clip_expectations_; template - void check(T shape, ClipOp clip_op, bool is_aa) { + void check(T shape, ClipOp clip_op, bool is_aa, bool is_oval = false) { ASSERT_LT(index_, clip_expectations_.size()) << label() << std::endl - << "extra clip shape = " << shape; + << "extra clip shape = " << shape << (is_oval ? " (oval)" : ""); auto expected = clip_expectations_[index_]; - EXPECT_EQ(expected.clip_op, clip_op) << label(); - EXPECT_EQ(expected.is_aa, is_aa) << label(); if (!std::holds_alternative(expected.shape)) { EXPECT_TRUE(std::holds_alternative(expected.shape)) << label() << ", expected type: " << expected.shape_name(); } else { EXPECT_EQ(std::get(expected.shape), shape) << label(); } + EXPECT_EQ(expected.is_oval, is_oval) << label(); + EXPECT_EQ(expected.clip_op, clip_op) << label(); + EXPECT_EQ(expected.is_aa, is_aa) << label(); index_++; } @@ -4570,9 +4619,47 @@ TEST_F(DisplayListTest, ClipRectNestedNonCullingComplex) { cull_dl->Dispatch(expector); } +TEST_F(DisplayListTest, ClipOvalCulling) { + auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + // A 10x10 rectangle extends 5x5 from the center to each corner. To have + // an oval that encompasses that rectangle, the radius must be at least + // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 + // on each side to barely contain the corners of the square. + auto encompassing_oval = clip.makeOutset(2.072f, 2.072f); + + DisplayListBuilder cull_builder; + cull_builder.ClipRect(clip, ClipOp::kIntersect, false); + cull_builder.ClipOval(encompassing_oval, ClipOp::kIntersect, false); + auto cull_dl = cull_builder.Build(); + + CLIP_EXPECTOR(expector); + expector.addExpectation(clip, ClipOp::kIntersect, false); + cull_dl->Dispatch(expector); +} + +TEST_F(DisplayListTest, ClipOvalNonCulling) { + auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + // A 10x10 rectangle extends 5x5 from the center to each corner. To have + // an oval that encompasses that rectangle, the radius must be at least + // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 + // on each side to barely exclude the corners of the square. + auto non_encompassing_oval = clip.makeOutset(2.071f, 2.071f); + + DisplayListBuilder cull_builder; + cull_builder.ClipRect(clip, ClipOp::kIntersect, false); + cull_builder.ClipOval(non_encompassing_oval, ClipOp::kIntersect, false); + auto cull_dl = cull_builder.Build(); + + CLIP_EXPECTOR(expector); + expector.addExpectation(clip, ClipOp::kIntersect, false); + expector.addOvalExpectation(non_encompassing_oval, ClipOp::kIntersect, false); + cull_dl->Dispatch(expector); +} + TEST_F(DisplayListTest, ClipRRectCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 2.0f, 2.0f); + ASSERT_FALSE(rrect.isOval()); DisplayListBuilder cull_builder; cull_builder.ClipRect(clip, ClipOp::kIntersect, false); @@ -4586,7 +4673,8 @@ TEST_F(DisplayListTest, ClipRRectCulling) { TEST_F(DisplayListTest, ClipRRectNonCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 12.0f, 12.0f); + auto rrect = SkRRect::MakeRectXY(clip.makeOutset(1.0f, 1.0f), 4.0f, 4.0f); + ASSERT_FALSE(rrect.isOval()); DisplayListBuilder cull_builder; cull_builder.ClipRect(clip, ClipOp::kIntersect, false); @@ -4661,9 +4749,52 @@ TEST_F(DisplayListTest, ClipPathRectNonCulling) { cull_dl->Dispatch(expector); } +TEST_F(DisplayListTest, ClipPathOvalCulling) { + auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + // A 10x10 rectangle extends 5x5 from the center to each corner. To have + // an oval that encompasses that rectangle, the radius must be at least + // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 + // on each side to barely contain the corners of the square. + auto encompassing_oval = clip.makeOutset(2.072f, 2.072f); + SkPath path; + path.addOval(encompassing_oval); + + DisplayListBuilder cull_builder; + cull_builder.ClipRect(clip, ClipOp::kIntersect, false); + cull_builder.ClipPath(path, ClipOp::kIntersect, false); + auto cull_dl = cull_builder.Build(); + + CLIP_EXPECTOR(expector); + expector.addExpectation(clip, ClipOp::kIntersect, false); + cull_dl->Dispatch(expector); +} + +TEST_F(DisplayListTest, ClipPathOvalNonCulling) { + auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + // A 10x10 rectangle extends 5x5 from the center to each corner. To have + // an oval that encompasses that rectangle, the radius must be at least + // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 + // on each side to barely exclude the corners of the square. + auto non_encompassing_oval = clip.makeOutset(2.071f, 2.071f); + SkPath path; + path.addOval(non_encompassing_oval); + + DisplayListBuilder cull_builder; + cull_builder.ClipRect(clip, ClipOp::kIntersect, false); + cull_builder.ClipPath(path, ClipOp::kIntersect, false); + auto cull_dl = cull_builder.Build(); + + CLIP_EXPECTOR(expector); + expector.addExpectation(clip, ClipOp::kIntersect, false); + // Builder will not cull this clip, but it will turn it into a ClipOval + expector.addOvalExpectation(non_encompassing_oval, ClipOp::kIntersect, false); + cull_dl->Dispatch(expector); +} + TEST_F(DisplayListTest, ClipPathRRectCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 2.0f, 2.0f); + ASSERT_FALSE(rrect.isOval()); SkPath path; path.addRRect(rrect); @@ -4679,7 +4810,8 @@ TEST_F(DisplayListTest, ClipPathRRectCulling) { TEST_F(DisplayListTest, ClipPathRRectNonCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 12.0f, 12.0f); + auto rrect = SkRRect::MakeRectXY(clip.makeOutset(1.0f, 1.0f), 4.0f, 4.0f); + ASSERT_FALSE(rrect.isOval()); SkPath path; path.addRRect(rrect); @@ -4724,5 +4856,235 @@ TEST_F(DisplayListTest, RecordLargeVertices) { } } +TEST_F(DisplayListTest, DrawRectRRectPromoteToDrawRect) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + + DisplayListBuilder builder; + builder.DrawRRect(SkRRect::MakeRect(rect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawRect(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawOvalRRectPromoteToDrawOval) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + + DisplayListBuilder builder; + builder.DrawRRect(SkRRect::MakeOval(rect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawOval(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawRectPathPromoteToDrawRect) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::Rect(rect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawRect(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawOvalPathPromoteToDrawOval) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::Oval(rect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawOval(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawRRectPathPromoteToDrawRRect) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect rrect = SkRRect::MakeRectXY(rect, 2.0f, 2.0f); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::RRect(rrect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawRRect(rrect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawRectRRectPathPromoteToDrawRect) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect rrect = SkRRect::MakeRect(rect); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::RRect(rrect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawRect(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawOvalRRectPathPromoteToDrawOval) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect rrect = SkRRect::MakeOval(rect); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::RRect(rrect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawOval(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipRectRRectPromoteToClipRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipRRect(SkRRect::MakeRect(clip_rect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipRect(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipOvalRRectPromoteToClipOval) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipRRect(SkRRect::MakeOval(clip_rect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipOval(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipRectPathPromoteToClipRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipPath(SkPath::Rect(clip_rect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipRect(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipOvalPathPromoteToClipOval) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipPath(SkPath::Oval(clip_rect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipOval(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipRRectPathPromoteToClipRRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect clip_rrect = SkRRect::MakeRectXY(clip_rect, 2.0f, 2.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipPath(SkPath::RRect(clip_rrect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipRRect(clip_rrect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipRectRRectPathPromoteToClipRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect clip_rrect = SkRRect::MakeRect(clip_rect); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipPath(SkPath::RRect(clip_rrect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipRect(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipOvalRRectPathPromoteToClipOval) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect clip_rrect = SkRRect::MakeOval(clip_rect); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipPath(SkPath::RRect(clip_rrect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipOval(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + } // namespace testing } // namespace flutter diff --git a/display_list/dl_builder.cc b/display_list/dl_builder.cc index 98772c0d7a3ab..9147661de26f1 100644 --- a/display_list/dl_builder.cc +++ b/display_list/dl_builder.cc @@ -963,14 +963,50 @@ void DisplayListBuilder::ClipRect(const SkRect& rect, break; } } +void DisplayListBuilder::ClipOval(const SkRect& bounds, + ClipOp clip_op, + bool is_aa) { + if (!bounds.isFinite()) { + return; + } + if (current_info().is_nop) { + return; + } + if (current_info().has_valid_clip && + clip_op == DlCanvas::ClipOp::kIntersect && + layer_local_state().oval_covers_cull(bounds)) { + return; + } + global_state().clipOval(bounds, clip_op, is_aa); + layer_local_state().clipOval(bounds, clip_op, is_aa); + if (global_state().is_cull_rect_empty() || + layer_local_state().is_cull_rect_empty()) { + current_info().is_nop = true; + return; + } + current_info().has_valid_clip = true; + checkForDeferredSave(); + switch (clip_op) { + case ClipOp::kIntersect: + Push(0, bounds, is_aa); + break; + case ClipOp::kDifference: + Push(0, bounds, is_aa); + break; + } +} void DisplayListBuilder::ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { + if (current_info().is_nop) { + return; + } if (rrect.isRect()) { clipRect(rrect.rect(), clip_op, is_aa); return; } - if (current_info().is_nop) { + if (rrect.isOval()) { + clipOval(rrect.rect(), clip_op, is_aa); return; } if (current_info().has_valid_clip && @@ -1008,12 +1044,11 @@ void DisplayListBuilder::ClipPath(const SkPath& path, this->clipRect(rect, clip_op, is_aa); return; } - SkRRect rrect; if (path.isOval(&rect)) { - rrect.setOval(rect); - this->clipRRect(rrect, clip_op, is_aa); + this->clipOval(rect, clip_op, is_aa); return; } + SkRRect rrect; if (path.isRRect(&rrect)) { this->clipRRect(rrect, clip_op, is_aa); return; @@ -1188,6 +1223,24 @@ void DisplayListBuilder::DrawDRRect(const SkRRect& outer, drawDRRect(outer, inner); } void DisplayListBuilder::drawPath(const SkPath& path) { + { + SkRect rect; + if (path.isRect(&rect)) { + drawRect(rect); + return; + } + if (path.isOval(&rect)) { + drawOval(rect); + return; + } + } + { + SkRRect rrect; + if (path.isRRect(&rrect)) { + drawRRect(rrect); + return; + } + } DisplayListAttributeFlags flags = kDrawPathFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect) { diff --git a/display_list/dl_builder.h b/display_list/dl_builder.h index b1a458f68eec9..dc75e2d37f6af 100644 --- a/display_list/dl_builder.h +++ b/display_list/dl_builder.h @@ -117,6 +117,10 @@ class DisplayListBuilder final : public virtual DlCanvas, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) override; // |DlCanvas| + void ClipOval(const SkRect& bounds, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) override; + // |DlCanvas| void ClipRRect(const SkRRect& rrect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) override; @@ -400,6 +404,10 @@ class DisplayListBuilder final : public virtual DlCanvas, ClipRect(rect, clip_op, is_aa); } // |DlOpReceiver| + void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override { + ClipOval(bounds, clip_op, is_aa); + } + // |DlOpReceiver| void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override { ClipRRect(rrect, clip_op, is_aa); } diff --git a/display_list/dl_canvas.h b/display_list/dl_canvas.h index ab505777aeae2..8fa4ad923f307 100644 --- a/display_list/dl_canvas.h +++ b/display_list/dl_canvas.h @@ -105,6 +105,9 @@ class DlCanvas { virtual void ClipRect(const SkRect& rect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) = 0; + virtual void ClipOval(const SkRect& bounds, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) = 0; virtual void ClipRRect(const SkRRect& rrect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) = 0; diff --git a/display_list/dl_op_receiver.h b/display_list/dl_op_receiver.h index 8de5dae62c4d7..dc85e379e4176 100644 --- a/display_list/dl_op_receiver.h +++ b/display_list/dl_op_receiver.h @@ -328,6 +328,7 @@ class DlOpReceiver { virtual void transformReset() = 0; virtual void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) = 0; + virtual void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) = 0; virtual void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) = 0; virtual void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) = 0; diff --git a/display_list/dl_op_records.h b/display_list/dl_op_records.h index 3ad6eebe8fc54..aeb0379e2371f 100644 --- a/display_list/dl_op_records.h +++ b/display_list/dl_op_records.h @@ -566,11 +566,11 @@ struct TransformResetOp final : TransformClipOpBase { // the header, but the Windows compiler keeps wanting to expand that // packing into more bytes than needed (even when they are declared as // packed bit fields!) -#define DEFINE_CLIP_SHAPE_OP(shapetype, clipop) \ - struct Clip##clipop##shapetype##Op final : TransformClipOpBase { \ - static constexpr auto kType = DisplayListOpType::kClip##clipop##shapetype; \ +#define DEFINE_CLIP_SHAPE_OP(shapename, shapetype, clipop) \ + struct Clip##clipop##shapename##Op final : TransformClipOpBase { \ + static constexpr auto kType = DisplayListOpType::kClip##clipop##shapename; \ \ - Clip##clipop##shapetype##Op(Sk##shapetype shape, bool is_aa) \ + Clip##clipop##shapename##Op(Sk##shapetype shape, bool is_aa) \ : is_aa(is_aa), shape(shape) {} \ \ const bool is_aa; \ @@ -578,15 +578,17 @@ struct TransformResetOp final : TransformClipOpBase { \ void dispatch(DispatchContext& ctx) const { \ if (op_needed(ctx)) { \ - ctx.receiver.clip##shapetype(shape, DlCanvas::ClipOp::k##clipop, \ + ctx.receiver.clip##shapename(shape, DlCanvas::ClipOp::k##clipop, \ is_aa); \ } \ } \ }; -DEFINE_CLIP_SHAPE_OP(Rect, Intersect) -DEFINE_CLIP_SHAPE_OP(RRect, Intersect) -DEFINE_CLIP_SHAPE_OP(Rect, Difference) -DEFINE_CLIP_SHAPE_OP(RRect, Difference) +DEFINE_CLIP_SHAPE_OP(Rect, Rect, Intersect) +DEFINE_CLIP_SHAPE_OP(Oval, Rect, Intersect) +DEFINE_CLIP_SHAPE_OP(RRect, RRect, Intersect) +DEFINE_CLIP_SHAPE_OP(Rect, Rect, Difference) +DEFINE_CLIP_SHAPE_OP(Oval, Rect, Difference) +DEFINE_CLIP_SHAPE_OP(RRect, RRect, Difference) #undef DEFINE_CLIP_SHAPE_OP #define DEFINE_CLIP_PATH_OP(clipop) \ diff --git a/display_list/skia/dl_sk_canvas.cc b/display_list/skia/dl_sk_canvas.cc index a7334f303ec4b..235b654f41bca 100644 --- a/display_list/skia/dl_sk_canvas.cc +++ b/display_list/skia/dl_sk_canvas.cc @@ -153,6 +153,12 @@ void DlSkCanvasAdapter::ClipRect(const SkRect& rect, delegate_->clipRect(rect, ToSk(clip_op), is_aa); } +void DlSkCanvasAdapter::ClipOval(const SkRect& bounds, + ClipOp clip_op, + bool is_aa) { + delegate_->clipRRect(SkRRect::MakeOval(bounds), ToSk(clip_op), is_aa); +} + void DlSkCanvasAdapter::ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/display_list/skia/dl_sk_canvas.h b/display_list/skia/dl_sk_canvas.h index c61f3f465455e..5ceebe561ef6b 100644 --- a/display_list/skia/dl_sk_canvas.h +++ b/display_list/skia/dl_sk_canvas.h @@ -72,6 +72,7 @@ class DlSkCanvasAdapter final : public virtual DlCanvas { SkMatrix GetTransform() const override; void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void ClipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/display_list/skia/dl_sk_dispatcher.cc b/display_list/skia/dl_sk_dispatcher.cc index 84c7115fb5fa4..819860d3fb184 100644 --- a/display_list/skia/dl_sk_dispatcher.cc +++ b/display_list/skia/dl_sk_dispatcher.cc @@ -122,6 +122,11 @@ void DlSkCanvasDispatcher::clipRect(const SkRect& rect, bool is_aa) { canvas_->clipRect(rect, ToSk(clip_op), is_aa); } +void DlSkCanvasDispatcher::clipOval(const SkRect& bounds, + ClipOp clip_op, + bool is_aa) { + canvas_->clipRRect(SkRRect::MakeOval(bounds), ToSk(clip_op), is_aa); +} void DlSkCanvasDispatcher::clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/display_list/skia/dl_sk_dispatcher.h b/display_list/skia/dl_sk_dispatcher.h index ef15f8152e736..384f722633677 100644 --- a/display_list/skia/dl_sk_dispatcher.h +++ b/display_list/skia/dl_sk_dispatcher.h @@ -51,6 +51,7 @@ class DlSkCanvasDispatcher : public virtual DlOpReceiver, void transformReset() override; void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/display_list/testing/dl_rendering_unittests.cc b/display_list/testing/dl_rendering_unittests.cc index 89102029e175b..1368f3e921fbe 100644 --- a/display_list/testing/dl_rendering_unittests.cc +++ b/display_list/testing/dl_rendering_unittests.cc @@ -2073,6 +2073,39 @@ class CanvasCompareTester { ctx.canvas->ClipRect(r_clip, ClipOp::kDifference, false); }) .with_diff_clip()); + // Skia lacks clipOval and requires us to make an oval SkRRect + SkRRect rr_oval_clip = SkRRect::MakeOval(r_clip); + RenderWith(testP, env, intersect_tolerance, + CaseParameters( + "Hard ClipOval", + [=](const SkSetupContext& ctx) { + ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kIntersect, + false); + }, + [=](const DlSetupContext& ctx) { + ctx.canvas->ClipOval(r_clip, ClipOp::kIntersect, false); + })); + RenderWith(testP, env, intersect_tolerance, + CaseParameters( + "AntiAlias ClipOval", + [=](const SkSetupContext& ctx) { + ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kIntersect, + true); + }, + [=](const DlSetupContext& ctx) { + ctx.canvas->ClipOval(r_clip, ClipOp::kIntersect, true); + })); + RenderWith(testP, env, diff_tolerance, + CaseParameters( + "Hard ClipOval Diff", + [=](const SkSetupContext& ctx) { + ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kDifference, + false); + }, + [=](const DlSetupContext& ctx) { + ctx.canvas->ClipOval(r_clip, ClipOp::kDifference, false); + }) + .with_diff_clip()); // This test RR clip used to use very small radii, but due to // optimizations in the HW rrect rasterization, this caused small // bulges in the corners of the RRect which were interpreted as @@ -2850,12 +2883,14 @@ TEST_F(DisplayListRendering, DrawDiagonalLines) { SkPoint p2 = SkPoint::Make(kRenderRight, kRenderBottom); SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderBottom); SkPoint p4 = SkPoint::Make(kRenderRight, kRenderTop); + // Adding some edge to edge diagonals that run through the points about + // 16 units in from the center of that edge. // Adding some edge center to edge center diagonals to better fill // out the RRect Clip so bounds checking sees less empty bounds space. - SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop); - SkPoint p6 = SkPoint::Make(kRenderRight, kRenderCenterY); - SkPoint p7 = SkPoint::Make(kRenderLeft, kRenderCenterY); - SkPoint p8 = SkPoint::Make(kRenderCenterX, kRenderBottom); + SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop + 15); + SkPoint p6 = SkPoint::Make(kRenderRight - 15, kRenderCenterY); + SkPoint p7 = SkPoint::Make(kRenderCenterX, kRenderBottom - 15); + SkPoint p8 = SkPoint::Make(kRenderLeft + 15, kRenderCenterY); CanvasCompareTester::RenderAll( // TestParameters( @@ -2880,9 +2915,13 @@ TEST_F(DisplayListRendering, DrawDiagonalLines) { .set_draw_line()); } -TEST_F(DisplayListRendering, DrawHorizontalLine) { - SkPoint p1 = SkPoint::Make(kRenderLeft, kRenderCenterY); - SkPoint p2 = SkPoint::Make(kRenderRight, kRenderCenterY); +TEST_F(DisplayListRendering, DrawHorizontalLines) { + SkPoint p1 = SkPoint::Make(kRenderLeft, kRenderTop + 16); + SkPoint p2 = SkPoint::Make(kRenderRight, kRenderTop + 16); + SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderCenterY); + SkPoint p4 = SkPoint::Make(kRenderRight, kRenderCenterY); + SkPoint p5 = SkPoint::Make(kRenderLeft, kRenderBottom - 16); + SkPoint p6 = SkPoint::Make(kRenderRight, kRenderBottom - 16); CanvasCompareTester::RenderAll( // TestParameters( @@ -2893,18 +2932,26 @@ TEST_F(DisplayListRendering, DrawHorizontalLine) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); ctx.canvas->drawLine(p1, p2, p); + ctx.canvas->drawLine(p3, p4, p); + ctx.canvas->drawLine(p5, p6, p); }, [=](const DlRenderContext& ctx) { // ctx.canvas->DrawLine(p1, p2, ctx.paint); + ctx.canvas->DrawLine(p3, p4, ctx.paint); + ctx.canvas->DrawLine(p5, p6, ctx.paint); }, kDrawHVLineFlags) .set_draw_line() .set_horizontal_line()); } -TEST_F(DisplayListRendering, DrawVerticalLine) { - SkPoint p1 = SkPoint::Make(kRenderCenterX, kRenderTop); - SkPoint p2 = SkPoint::Make(kRenderCenterY, kRenderBottom); +TEST_F(DisplayListRendering, DrawVerticalLines) { + SkPoint p1 = SkPoint::Make(kRenderLeft + 16, kRenderTop); + SkPoint p2 = SkPoint::Make(kRenderLeft + 16, kRenderBottom); + SkPoint p3 = SkPoint::Make(kRenderCenterX, kRenderTop); + SkPoint p4 = SkPoint::Make(kRenderCenterX, kRenderBottom); + SkPoint p5 = SkPoint::Make(kRenderRight - 16, kRenderTop); + SkPoint p6 = SkPoint::Make(kRenderRight - 16, kRenderBottom); CanvasCompareTester::RenderAll( // TestParameters( @@ -2915,9 +2962,13 @@ TEST_F(DisplayListRendering, DrawVerticalLine) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); ctx.canvas->drawLine(p1, p2, p); + ctx.canvas->drawLine(p3, p4, p); + ctx.canvas->drawLine(p5, p6, p); }, [=](const DlRenderContext& ctx) { // ctx.canvas->DrawLine(p1, p2, ctx.paint); + ctx.canvas->DrawLine(p3, p4, ctx.paint); + ctx.canvas->DrawLine(p5, p6, ctx.paint); }, kDrawHVLineFlags) .set_draw_line() @@ -2929,12 +2980,14 @@ TEST_F(DisplayListRendering, DrawDiagonalDashedLines) { SkPoint p2 = SkPoint::Make(kRenderRight, kRenderBottom); SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderBottom); SkPoint p4 = SkPoint::Make(kRenderRight, kRenderTop); + // Adding some edge to edge diagonals that run through the points about + // 16 units in from the center of that edge. // Adding some edge center to edge center diagonals to better fill // out the RRect Clip so bounds checking sees less empty bounds space. - SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop); - SkPoint p6 = SkPoint::Make(kRenderRight, kRenderCenterY); - SkPoint p7 = SkPoint::Make(kRenderLeft, kRenderCenterY); - SkPoint p8 = SkPoint::Make(kRenderCenterX, kRenderBottom); + SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop + 15); + SkPoint p6 = SkPoint::Make(kRenderRight - 15, kRenderCenterY); + SkPoint p7 = SkPoint::Make(kRenderCenterX, kRenderBottom - 15); + SkPoint p8 = SkPoint::Make(kRenderLeft + 15, kRenderCenterY); // Full diagonals are 100x100 which are 140 in length // Dashing them with 25 on, 5 off means that the last @@ -2955,7 +3008,7 @@ TEST_F(DisplayListRendering, DrawDiagonalDashedLines) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); SkScalar intervals[2] = {25.0f, 5.0f}; - p.setPathEffect(SkDashPathEffect::Make(intervals, 2.0f, 0.0f)); + p.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0.0f)); ctx.canvas->drawLine(p1, p2, p); ctx.canvas->drawLine(p3, p4, p); ctx.canvas->drawLine(p5, p6, p); @@ -3125,7 +3178,7 @@ TEST_F(DisplayListRendering, DrawPointsAsPoints) { const SkScalar x3 = kRenderCenterX + 0.1; const SkScalar x4 = (kRenderRight + kRenderCenterX) * 0.5; const SkScalar x5 = kRenderRight - 16; - const SkScalar x6 = kRenderRight; + const SkScalar x6 = kRenderRight - 1; const SkScalar y0 = kRenderTop; const SkScalar y1 = kRenderTop + 16; @@ -3133,7 +3186,7 @@ TEST_F(DisplayListRendering, DrawPointsAsPoints) { const SkScalar y3 = kRenderCenterY + 0.1; const SkScalar y4 = (kRenderBottom + kRenderCenterY) * 0.5; const SkScalar y5 = kRenderBottom - 16; - const SkScalar y6 = kRenderBottom; + const SkScalar y6 = kRenderBottom - 1; // clang-format off const SkPoint points[] = { @@ -3177,7 +3230,7 @@ TEST_F(DisplayListRendering, DrawPointsAsLines) { const SkScalar y0 = kRenderTop; const SkScalar y1 = kRenderTop + 16; const SkScalar y2 = kRenderBottom - 16; - const SkScalar y3 = kRenderBottom; + const SkScalar y3 = kRenderBottom - 1; // clang-format off const SkPoint points[] = { @@ -3226,10 +3279,12 @@ TEST_F(DisplayListRendering, DrawPointsAsPolygon) { SkPoint::Make(kRenderRight, kRenderBottom), SkPoint::Make(kRenderLeft, kRenderBottom), SkPoint::Make(kRenderLeft, kRenderTop), - SkPoint::Make(kRenderCenterX, kRenderTop), - SkPoint::Make(kRenderRight, kRenderCenterY), - SkPoint::Make(kRenderCenterX, kRenderBottom), - SkPoint::Make(kRenderLeft, kRenderCenterY), + + SkPoint::Make(kRenderCenterX, kRenderTop + 15), + SkPoint::Make(kRenderRight - 15, kRenderCenterY), + SkPoint::Make(kRenderCenterX, kRenderBottom - 15), + SkPoint::Make(kRenderLeft + 15, kRenderCenterY), + SkPoint::Make(kRenderCenterX, kRenderTop + 15), }; const int count1 = sizeof(points1) / sizeof(points1[0]); @@ -3730,7 +3785,7 @@ TEST_F(DisplayListRendering, DrawShadow) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 5; + const SkScalar elevation = 7; CanvasCompareTester::RenderAll( // TestParameters( @@ -3756,7 +3811,7 @@ TEST_F(DisplayListRendering, DrawShadowTransparentOccluder) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 5; + const SkScalar elevation = 7; CanvasCompareTester::RenderAll( // TestParameters( @@ -3782,7 +3837,7 @@ TEST_F(DisplayListRendering, DrawShadowDpr) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 5; + const SkScalar elevation = 7; CanvasCompareTester::RenderAll( // TestParameters( diff --git a/display_list/testing/dl_test_snippets.cc b/display_list/testing/dl_test_snippets.cc index e5ad4b2f365dc..16c0edb5d4468 100644 --- a/display_list/testing/dl_test_snippets.cc +++ b/display_list/testing/dl_test_snippets.cc @@ -424,6 +424,30 @@ std::vector CreateAllClipOps() { r.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, false); }}, }}, + {"ClipOval", + { + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds, DlCanvas::ClipOp::kIntersect, true); + }}, + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds.makeOffset(1, 1), + DlCanvas::ClipOp::kIntersect, true); + }}, + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds, DlCanvas::ClipOp::kIntersect, false); + }}, + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds, DlCanvas::ClipOp::kDifference, true); + }}, + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds, DlCanvas::ClipOp::kDifference, false); + }}, + }}, {"ClipRRect", { {1, 64, 0, @@ -479,11 +503,16 @@ std::vector CreateAllClipOps() { [](DlOpReceiver& r) { r.clipPath(kTestPathRect, DlCanvas::ClipOp::kIntersect, true); }}, - // clipPath(oval) becomes clipRRect - {1, 64, 0, + // clipPath(oval) becomes clipOval + {1, 24, 0, [](DlOpReceiver& r) { r.clipPath(kTestPathOval, DlCanvas::ClipOp::kIntersect, true); }}, + // clipPath(rrect) becomes clipRRect + {1, 64, 0, + [](DlOpReceiver& r) { + r.clipPath(kTestPathRRect, DlCanvas::ClipOp::kIntersect, true); + }}, }}, }; } @@ -637,8 +666,11 @@ std::vector CreateAllRenderingOps() { {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath1); }}, {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath2); }}, {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath3); }}, - {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }}, - {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }}, + // oval and rect paths are redirected to drawRect and drawOval + {1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }}, + {1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }}, + // rrect path is redirected to drawRRect + {1, 56, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRRect); }}, }}, {"DrawArc", { diff --git a/display_list/testing/dl_test_snippets.h b/display_list/testing/dl_test_snippets.h index 16d740c2fb6a0..733ce67364034 100644 --- a/display_list/testing/dl_test_snippets.h +++ b/display_list/testing/dl_test_snippets.h @@ -183,6 +183,7 @@ static const SkRRect kTestInnerRRect = SkRRect::MakeRectXY(kTestBounds.makeInset(5, 5), 2, 2); static const SkPath kTestPathRect = SkPath::Rect(kTestBounds); static const SkPath kTestPathOval = SkPath::Oval(kTestBounds); +static const SkPath kTestPathRRect = SkPath::RRect(kTestRRect); static const SkPath kTestPath1 = SkPath::Polygon({{0, 0}, {10, 10}, {10, 0}, {0, 10}}, true); static const SkPath kTestPath2 = diff --git a/display_list/utils/dl_matrix_clip_tracker.cc b/display_list/utils/dl_matrix_clip_tracker.cc index 748cf07a8385a..86f3cff46a6d9 100644 --- a/display_list/utils/dl_matrix_clip_tracker.cc +++ b/display_list/utils/dl_matrix_clip_tracker.cc @@ -74,6 +74,24 @@ void DisplayListMatrixClipState::clipRect(const DlRect& rect, } } +void DisplayListMatrixClipState::clipOval(const DlRect& bounds, + ClipOp op, + bool is_aa) { + if (!bounds.IsFinite()) { + return; + } + switch (op) { + case DlCanvas::ClipOp::kIntersect: + adjustCullRect(bounds, op, is_aa); + break; + case DlCanvas::ClipOp::kDifference: + if (oval_covers_cull(bounds)) { + cull_rect_ = DlRect(); + } + break; + } +} + void DisplayListMatrixClipState::clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) { diff --git a/display_list/utils/dl_matrix_clip_tracker.h b/display_list/utils/dl_matrix_clip_tracker.h index 59c9880bd3bd7..4a6198d75a3e1 100644 --- a/display_list/utils/dl_matrix_clip_tracker.h +++ b/display_list/utils/dl_matrix_clip_tracker.h @@ -149,6 +149,10 @@ class DisplayListMatrixClipState { void clipRect(const SkRect& rect, ClipOp op, bool is_aa) { clipRect(ToDlRect(rect), op, is_aa); } + void clipOval(const DlRect& bounds, ClipOp op, bool is_aa); + void clipOval(const SkRect& bounds, ClipOp op, bool is_aa) { + clipRect(ToDlRect(bounds), op, is_aa); + } void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa); void clipPath(const SkPath& path, ClipOp op, bool is_aa); diff --git a/display_list/utils/dl_receiver_utils.h b/display_list/utils/dl_receiver_utils.h index d50cb00cba057..bb6ce6539f653 100644 --- a/display_list/utils/dl_receiver_utils.h +++ b/display_list/utils/dl_receiver_utils.h @@ -44,6 +44,9 @@ class IgnoreClipDispatchHelper : public virtual DlOpReceiver { void clipRect(const SkRect& rect, DlCanvas::ClipOp clip_op, bool is_aa) override {} + void clipOval(const SkRect& bounds, + DlCanvas::ClipOp clip_op, + bool is_aa) override {} void clipRRect(const SkRRect& rrect, DlCanvas::ClipOp clip_op, bool is_aa) override {} diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index aaed5e44f647b..089e5259ffa5a 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -723,6 +723,14 @@ void DlDispatcherBase::clipRect(const SkRect& rect, ToClipOperation(clip_op)); } +// |flutter::DlOpReceiver| +void DlDispatcherBase::clipOval(const SkRect& bounds, + ClipOp clip_op, + bool is_aa) { + GetCanvas().ClipOval(skia_conversions::ToRect(bounds), + ToClipOperation(clip_op)); +} + // |flutter::DlOpReceiver| void DlDispatcherBase::clipRRect(const SkRRect& rrect, ClipOp sk_op, diff --git a/impeller/display_list/dl_dispatcher.h b/impeller/display_list/dl_dispatcher.h index 7349ca7e4fd84..294616b748776 100644 --- a/impeller/display_list/dl_dispatcher.h +++ b/impeller/display_list/dl_dispatcher.h @@ -123,6 +123,9 @@ class DlDispatcherBase : public flutter::DlOpReceiver { // |flutter::DlOpReceiver| void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + // |flutter::DlOpReceiver| + void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; + // |flutter::DlOpReceiver| void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; diff --git a/testing/display_list_testing.cc b/testing/display_list_testing.cc index 8cf84bc270242..ce831ca247813 100644 --- a/testing/display_list_testing.cc +++ b/testing/display_list_testing.cc @@ -742,6 +742,14 @@ void DisplayListStreamDispatcher::clipRect(const SkRect& rect, ClipOp clip_op, << "isaa: " << is_aa << ");" << std::endl; } +void DisplayListStreamDispatcher::clipOval(const SkRect& bounds, ClipOp clip_op, + bool is_aa) { + startl() << "clipOval(" + << bounds << ", " + << clip_op << ", " + << "isaa: " << is_aa + << ");" << std::endl; +} void DisplayListStreamDispatcher::clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/testing/display_list_testing.h b/testing/display_list_testing.h index b710e1e22af45..2ccb011dedcf0 100644 --- a/testing/display_list_testing.h +++ b/testing/display_list_testing.h @@ -118,6 +118,7 @@ class DisplayListStreamDispatcher final : public DlOpReceiver { void transformReset() override; void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc index 695678e23a0ee..03627f722fbaa 100644 --- a/testing/mock_canvas.cc +++ b/testing/mock_canvas.cc @@ -214,6 +214,13 @@ void MockCanvas::ClipRect(const SkRect& rect, ClipOp op, bool is_aa) { state_stack_.back().clipRect(rect, op, is_aa); } +void MockCanvas::ClipOval(const SkRect& bounds, ClipOp op, bool is_aa) { + ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle; + draw_calls_.emplace_back( + DrawCall{current_layer_, ClipOvalData{bounds, op, style}}); + state_stack_.back().clipOval(bounds, op, is_aa); +} + void MockCanvas::ClipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) { ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle; draw_calls_.emplace_back( @@ -520,6 +527,16 @@ std::ostream& operator<<(std::ostream& os, return os << data.rect << " " << data.clip_op << " " << data.style; } +bool operator==(const MockCanvas::ClipOvalData& a, + const MockCanvas::ClipOvalData& b) { + return a.bounds == b.bounds && a.clip_op == b.clip_op && a.style == b.style; +} + +std::ostream& operator<<(std::ostream& os, + const MockCanvas::ClipOvalData& data) { + return os << data.bounds << " " << data.clip_op << " " << data.style; +} + bool operator==(const MockCanvas::ClipRRectData& a, const MockCanvas::ClipRRectData& b) { return a.rrect == b.rrect && a.clip_op == b.clip_op && a.style == b.style; diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h index f15e0ec54adf2..7384d5ecf578a 100644 --- a/testing/mock_canvas.h +++ b/testing/mock_canvas.h @@ -114,6 +114,12 @@ class MockCanvas final : public DlCanvas { ClipEdgeStyle style; }; + struct ClipOvalData { + SkRect bounds; + ClipOp clip_op; + ClipEdgeStyle style; + }; + struct ClipRRectData { SkRRect rrect; ClipOp clip_op; @@ -145,6 +151,7 @@ class MockCanvas final : public DlCanvas { DrawDisplayListData, DrawShadowData, ClipRectData, + ClipOvalData, ClipRRectData, ClipPathData, DrawPaintData>; @@ -206,6 +213,7 @@ class MockCanvas final : public DlCanvas { SkMatrix GetTransform() const override; void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void ClipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; From d506512f4aa38f61cf49737fe9e8d23c2d4e6042 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 01:06:54 -0400 Subject: [PATCH 71/88] Roll Fuchsia Linux SDK from gBWzGuicxu76K82lg... to H_P7EHb4zXXV-Eiik... (#53624) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/fuchsia-linux-sdk-flutter-engine Please CC jimgraham@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_fuchsia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index a6612ff009e0a..80fff618010ff 100644 --- a/DEPS +++ b/DEPS @@ -969,7 +969,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/sdk/core/linux-amd64', - 'version': 'gBWzGuicxu76K82lgv4GlyIQgzT4_cL5amo3g4mbDqsC' + 'version': 'H_P7EHb4zXXV-EiikVhe0bDOaA0cSQX-GfLU-S2aNJ8C' } ], 'condition': 'download_fuchsia_deps and not download_fuchsia_sdk', diff --git a/ci/licenses_golden/licenses_fuchsia b/ci/licenses_golden/licenses_fuchsia index e0ad27fa38be0..b4f7936ee39d7 100644 --- a/ci/licenses_golden/licenses_fuchsia +++ b/ci/licenses_golden/licenses_fuchsia @@ -1,4 +1,4 @@ -Signature: d6e7bea50a46dc07269b7728a08ef2d8 +Signature: b5809c0421572d6946e87cdf08fd2593 ==================================================================================================== LIBRARY: fuchsia_sdk From 409b41db71de3df4ce0c7c85f869c51ec199f13b Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 01:54:23 -0400 Subject: [PATCH 72/88] Roll Skia from 1700e3962acd to 2204428a75ca (1 revision) (#53625) https://skia.googlesource.com/skia.git/+log/1700e3962acd..2204428a75ca 2024-06-28 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Dawn from 0a3b1b98cce7 to 9281ee0a120f (15 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 80fff618010ff..9265678c79fea 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '1700e3962acdcc196b8548caec4f0bc83cdd4a9a', + 'skia_revision': '2204428a75cab1468f3d5bfffa938e7adb31f372', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 9f528e76266def0ec420dff790cda940f4b5aa39 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 02:02:10 -0400 Subject: [PATCH 73/88] Roll Dart SDK from 0820b0766ac9 to 4005e5f1fb8e (1 revision) (#53626) https://dart.googlesource.com/sdk.git/+log/0820b0766ac9..4005e5f1fb8e 2024-06-28 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-312.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_dart | 4 ++-- sky/packages/sky_engine/LICENSE | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DEPS b/DEPS index 9265678c79fea..725a8ac700396 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '0820b0766ac9656023394840538fe9ab70d55f0a', + 'dart_revision': '4005e5f1fb8e9eeb3ad5b204576248bbf7d15eee', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index 2dca21633882c..b57d1e395ad98 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: 047011981704cb1b5f4371c54ad1fb40 +Signature: b088512dc2eb2a8ff1d4b8b5a28a9a39 ==================================================================================================== LIBRARY: dart @@ -4751,7 +4751,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/0820b0766ac9656023394840538fe9ab70d55f0a +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/4005e5f1fb8e9eeb3ad5b204576248bbf7d15eee /third_party/fallback_root_certificates/ ==================================================================================================== diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index 9d9af8da25a69..32e51ea158914 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31897,7 +31897,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/0820b0766ac9656023394840538fe9ab70d55f0a +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/4005e5f1fb8e9eeb3ad5b204576248bbf7d15eee /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From 9dd06ef80bb231d376b6b485c707228b3597782d Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 04:23:39 -0400 Subject: [PATCH 74/88] Roll Skia from 2204428a75ca to 6650fcc6d054 (2 revisions) (#53627) https://skia.googlesource.com/skia.git/+log/2204428a75ca..6650fcc6d054 2024-06-28 skia-autoroll@skia-public.iam.gserviceaccount.com Roll ANGLE from 46dd6457f4bf to e86ba9abe996 (5 revisions) 2024-06-28 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Skia Infra from 79660091faba to 40eb79dec2d6 (5 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 725a8ac700396..858a57078e713 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '2204428a75cab1468f3d5bfffa938e7adb31f372', + 'skia_revision': '6650fcc6d05496cd06f7868e126f6f8c3b84ab09', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index ad0ef2fd3ca28..7c4d83b8341bc 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 3050d088dea416486ead5defb846dc46 +Signature: 7824470b0fe3d3fa2b92db248464d861 ==================================================================================================== LIBRARY: etc1 From 51a0c20caeb867ddd6bd51d81a0d2f05623d5b5b Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 06:49:36 -0400 Subject: [PATCH 75/88] Roll Skia from 6650fcc6d054 to cd77153f20a8 (1 revision) (#53628) https://skia.googlesource.com/skia.git/+log/6650fcc6d054..cd77153f20a8 2024-06-28 skia-autoroll@skia-public.iam.gserviceaccount.com Roll vulkan-deps from 117f1e2fcf1c to 6583f5d23919 (2 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 858a57078e713..15579e818d1ef 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '6650fcc6d05496cd06f7868e126f6f8c3b84ab09', + 'skia_revision': 'cd77153f20a8331ee4f8a8eb1ff956fbdc441692', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From dcc909d39561f6a486f861fcb61298b5b615ec7a Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 06:55:38 -0400 Subject: [PATCH 76/88] Roll Dart SDK from 4005e5f1fb8e to 341dbaf977a3 (1 revision) (#53630) https://dart.googlesource.com/sdk.git/+log/4005e5f1fb8e..341dbaf977a3 2024-06-28 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-313.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_dart | 4 ++-- sky/packages/sky_engine/LICENSE | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DEPS b/DEPS index 15579e818d1ef..c13078af9595a 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '4005e5f1fb8e9eeb3ad5b204576248bbf7d15eee', + 'dart_revision': '341dbaf977a3ca3ef9261945e3c024ac5de14fc5', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index b57d1e395ad98..912d07db391f4 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: b088512dc2eb2a8ff1d4b8b5a28a9a39 +Signature: fa571bde6d9d9c4abb072e5e985c162f ==================================================================================================== LIBRARY: dart @@ -4751,7 +4751,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/4005e5f1fb8e9eeb3ad5b204576248bbf7d15eee +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/341dbaf977a3ca3ef9261945e3c024ac5de14fc5 /third_party/fallback_root_certificates/ ==================================================================================================== diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index 32e51ea158914..9bbb5c41d1b76 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31897,7 +31897,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/4005e5f1fb8e9eeb3ad5b204576248bbf7d15eee +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/341dbaf977a3ca3ef9261945e3c024ac5de14fc5 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From e514e59f47a866f156703bf1793a09c3bee94997 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 28 Jun 2024 04:07:21 -0700 Subject: [PATCH 77/88] Revert "[DisplayList] Add support for clipOval to leverage Impeller optimization" (#53629) Reverts flutter/engine#53622 There were some golden changes which might be minor, but they weren't expected. Also, I noticed a problem in reducing drawPath down to drawRect and drawOval - that should not be done if the path has the inverse fill flag set... --- display_list/display_list.h | 2 - display_list/display_list_unittests.cc | 424 ++---------------- display_list/dl_builder.cc | 61 +-- display_list/dl_builder.h | 8 - display_list/dl_canvas.h | 3 - display_list/dl_op_receiver.h | 1 - display_list/dl_op_records.h | 20 +- display_list/skia/dl_sk_canvas.cc | 6 - display_list/skia/dl_sk_canvas.h | 1 - display_list/skia/dl_sk_dispatcher.cc | 5 - display_list/skia/dl_sk_dispatcher.h | 1 - .../testing/dl_rendering_unittests.cc | 105 ++--- display_list/testing/dl_test_snippets.cc | 40 +- display_list/testing/dl_test_snippets.h | 1 - display_list/utils/dl_matrix_clip_tracker.cc | 18 - display_list/utils/dl_matrix_clip_tracker.h | 4 - display_list/utils/dl_receiver_utils.h | 3 - impeller/display_list/dl_dispatcher.cc | 8 - impeller/display_list/dl_dispatcher.h | 3 - testing/display_list_testing.cc | 8 - testing/display_list_testing.h | 1 - testing/mock_canvas.cc | 17 - testing/mock_canvas.h | 8 - 23 files changed, 73 insertions(+), 675 deletions(-) diff --git a/display_list/display_list.h b/display_list/display_list.h index bb67c435cc6d7..35c19ef9d4a0b 100644 --- a/display_list/display_list.h +++ b/display_list/display_list.h @@ -98,11 +98,9 @@ namespace flutter { V(TransformReset) \ \ V(ClipIntersectRect) \ - V(ClipIntersectOval) \ V(ClipIntersectRRect) \ V(ClipIntersectPath) \ V(ClipDifferenceRect) \ - V(ClipDifferenceOval) \ V(ClipDifferenceRRect) \ V(ClipDifferencePath) \ \ diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index 13902b621a241..635d38af7c8a9 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -3439,9 +3439,11 @@ TEST_F(DisplayListTest, ImpellerPathPreferenceIsHonored) { }; DisplayListBuilder builder; - builder.DrawPath(kTestPath1, DlPaint()); - builder.ClipPath(kTestPath1, ClipOp::kIntersect, true); - builder.DrawShadow(kTestPath1, DlColor::kBlue(), 1.0f, true, 1.0f); + builder.DrawPath(SkPath::Rect(SkRect::MakeLTRB(0, 0, 100, 100)), DlPaint()); + builder.ClipPath(SkPath::Rect(SkRect::MakeLTRB(0, 0, 100, 100)), + ClipOp::kIntersect, true); + builder.DrawShadow(SkPath::Rect(SkRect::MakeLTRB(20, 20, 80, 80)), + DlColor::kBlue(), 1.0f, true, 1.0f); auto display_list = builder.Build(); { @@ -4330,66 +4332,36 @@ TEST_F(DisplayListTest, DrawDisplayListForwardsBackdropFlag) { #define CLIP_EXPECTOR(name) ClipExpector name(__FILE__, __LINE__) -struct ClipExpectation { - std::variant shape; - bool is_oval; - ClipOp clip_op; - bool is_aa; - - std::string shape_name() { - switch (shape.index()) { - case 0: - return is_oval ? "SkOval" : "SkRect"; - case 1: - return "SkRRect"; - case 2: - return "SkPath"; - default: - return "Unknown"; - } - } -}; - -::std::ostream& operator<<(::std::ostream& os, const ClipExpectation& expect) { - os << "Expectation("; - switch (expect.shape.index()) { - case 0: - os << std::get(expect.shape); - if (expect.is_oval) { - os << " (oval)"; - } - break; - case 1: - os << std::get(expect.shape); - break; - case 2: - os << std::get(expect.shape); - break; - case 3: - os << "Unknown"; - } - os << ", " << expect.clip_op; - os << ", " << expect.is_aa; - os << ")"; - return os; -} - class ClipExpector : public virtual DlOpReceiver, virtual IgnoreAttributeDispatchHelper, virtual IgnoreTransformDispatchHelper, virtual IgnoreDrawDispatchHelper { public: + struct Expectation { + std::variant shape; + ClipOp clip_op; + bool is_aa; + + std::string shape_name() { + switch (shape.index()) { + case 0: + return "SkRect"; + case 1: + return "SkRRect"; + case 2: + return "SkPath"; + default: + return "Unknown"; + } + } + }; + // file and line supplied automatically from CLIP_EXPECTOR macro explicit ClipExpector(const std::string& file, int line) : file_(file), line_(line) {} ~ClipExpector() { // EXPECT_EQ(index_, clip_expectations_.size()) << label(); - while (index_ < clip_expectations_.size()) { - auto expect = clip_expectations_[index_]; - FML_LOG(ERROR) << "leftover clip shape[" << index_ << "] = " << expect; - index_++; - } } ClipExpector& addExpectation(const SkRect& rect, @@ -4397,19 +4369,6 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = rect, - .is_oval = false, - .clip_op = clip_op, - .is_aa = is_aa, - }); - return *this; - } - - ClipExpector& addOvalExpectation(const SkRect& rect, - ClipOp clip_op = ClipOp::kIntersect, - bool is_aa = false) { - clip_expectations_.push_back({ - .shape = rect, - .is_oval = true, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4421,7 +4380,6 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = rrect, - .is_oval = false, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4433,7 +4391,6 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = path, - .is_oval = false, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4445,11 +4402,6 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa) override { check(rect, clip_op, is_aa); } - void clipOval(const SkRect& bounds, - DlCanvas::ClipOp clip_op, - bool is_aa) override { - check(bounds, clip_op, is_aa, true); - } void clipRRect(const SkRRect& rrect, DlCanvas::ClipOp clip_op, bool is_aa) override { @@ -4463,23 +4415,22 @@ class ClipExpector : public virtual DlOpReceiver, private: size_t index_ = 0; - std::vector clip_expectations_; + std::vector clip_expectations_; template - void check(T shape, ClipOp clip_op, bool is_aa, bool is_oval = false) { + void check(T shape, ClipOp clip_op, bool is_aa) { ASSERT_LT(index_, clip_expectations_.size()) << label() << std::endl - << "extra clip shape = " << shape << (is_oval ? " (oval)" : ""); + << "extra clip shape = " << shape; auto expected = clip_expectations_[index_]; + EXPECT_EQ(expected.clip_op, clip_op) << label(); + EXPECT_EQ(expected.is_aa, is_aa) << label(); if (!std::holds_alternative(expected.shape)) { EXPECT_TRUE(std::holds_alternative(expected.shape)) << label() << ", expected type: " << expected.shape_name(); } else { EXPECT_EQ(std::get(expected.shape), shape) << label(); } - EXPECT_EQ(expected.is_oval, is_oval) << label(); - EXPECT_EQ(expected.clip_op, clip_op) << label(); - EXPECT_EQ(expected.is_aa, is_aa) << label(); index_++; } @@ -4619,47 +4570,9 @@ TEST_F(DisplayListTest, ClipRectNestedNonCullingComplex) { cull_dl->Dispatch(expector); } -TEST_F(DisplayListTest, ClipOvalCulling) { - auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - // A 10x10 rectangle extends 5x5 from the center to each corner. To have - // an oval that encompasses that rectangle, the radius must be at least - // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 - // on each side to barely contain the corners of the square. - auto encompassing_oval = clip.makeOutset(2.072f, 2.072f); - - DisplayListBuilder cull_builder; - cull_builder.ClipRect(clip, ClipOp::kIntersect, false); - cull_builder.ClipOval(encompassing_oval, ClipOp::kIntersect, false); - auto cull_dl = cull_builder.Build(); - - CLIP_EXPECTOR(expector); - expector.addExpectation(clip, ClipOp::kIntersect, false); - cull_dl->Dispatch(expector); -} - -TEST_F(DisplayListTest, ClipOvalNonCulling) { - auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - // A 10x10 rectangle extends 5x5 from the center to each corner. To have - // an oval that encompasses that rectangle, the radius must be at least - // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 - // on each side to barely exclude the corners of the square. - auto non_encompassing_oval = clip.makeOutset(2.071f, 2.071f); - - DisplayListBuilder cull_builder; - cull_builder.ClipRect(clip, ClipOp::kIntersect, false); - cull_builder.ClipOval(non_encompassing_oval, ClipOp::kIntersect, false); - auto cull_dl = cull_builder.Build(); - - CLIP_EXPECTOR(expector); - expector.addExpectation(clip, ClipOp::kIntersect, false); - expector.addOvalExpectation(non_encompassing_oval, ClipOp::kIntersect, false); - cull_dl->Dispatch(expector); -} - TEST_F(DisplayListTest, ClipRRectCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 2.0f, 2.0f); - ASSERT_FALSE(rrect.isOval()); DisplayListBuilder cull_builder; cull_builder.ClipRect(clip, ClipOp::kIntersect, false); @@ -4673,8 +4586,7 @@ TEST_F(DisplayListTest, ClipRRectCulling) { TEST_F(DisplayListTest, ClipRRectNonCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - auto rrect = SkRRect::MakeRectXY(clip.makeOutset(1.0f, 1.0f), 4.0f, 4.0f); - ASSERT_FALSE(rrect.isOval()); + auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 12.0f, 12.0f); DisplayListBuilder cull_builder; cull_builder.ClipRect(clip, ClipOp::kIntersect, false); @@ -4749,52 +4661,9 @@ TEST_F(DisplayListTest, ClipPathRectNonCulling) { cull_dl->Dispatch(expector); } -TEST_F(DisplayListTest, ClipPathOvalCulling) { - auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - // A 10x10 rectangle extends 5x5 from the center to each corner. To have - // an oval that encompasses that rectangle, the radius must be at least - // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 - // on each side to barely contain the corners of the square. - auto encompassing_oval = clip.makeOutset(2.072f, 2.072f); - SkPath path; - path.addOval(encompassing_oval); - - DisplayListBuilder cull_builder; - cull_builder.ClipRect(clip, ClipOp::kIntersect, false); - cull_builder.ClipPath(path, ClipOp::kIntersect, false); - auto cull_dl = cull_builder.Build(); - - CLIP_EXPECTOR(expector); - expector.addExpectation(clip, ClipOp::kIntersect, false); - cull_dl->Dispatch(expector); -} - -TEST_F(DisplayListTest, ClipPathOvalNonCulling) { - auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - // A 10x10 rectangle extends 5x5 from the center to each corner. To have - // an oval that encompasses that rectangle, the radius must be at least - // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 - // on each side to barely exclude the corners of the square. - auto non_encompassing_oval = clip.makeOutset(2.071f, 2.071f); - SkPath path; - path.addOval(non_encompassing_oval); - - DisplayListBuilder cull_builder; - cull_builder.ClipRect(clip, ClipOp::kIntersect, false); - cull_builder.ClipPath(path, ClipOp::kIntersect, false); - auto cull_dl = cull_builder.Build(); - - CLIP_EXPECTOR(expector); - expector.addExpectation(clip, ClipOp::kIntersect, false); - // Builder will not cull this clip, but it will turn it into a ClipOval - expector.addOvalExpectation(non_encompassing_oval, ClipOp::kIntersect, false); - cull_dl->Dispatch(expector); -} - TEST_F(DisplayListTest, ClipPathRRectCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 2.0f, 2.0f); - ASSERT_FALSE(rrect.isOval()); SkPath path; path.addRRect(rrect); @@ -4810,8 +4679,7 @@ TEST_F(DisplayListTest, ClipPathRRectCulling) { TEST_F(DisplayListTest, ClipPathRRectNonCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - auto rrect = SkRRect::MakeRectXY(clip.makeOutset(1.0f, 1.0f), 4.0f, 4.0f); - ASSERT_FALSE(rrect.isOval()); + auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 12.0f, 12.0f); SkPath path; path.addRRect(rrect); @@ -4856,235 +4724,5 @@ TEST_F(DisplayListTest, RecordLargeVertices) { } } -TEST_F(DisplayListTest, DrawRectRRectPromoteToDrawRect) { - SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - - DisplayListBuilder builder; - builder.DrawRRect(SkRRect::MakeRect(rect), DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.DrawRect(rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, DrawOvalRRectPromoteToDrawOval) { - SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - - DisplayListBuilder builder; - builder.DrawRRect(SkRRect::MakeOval(rect), DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.DrawOval(rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, DrawRectPathPromoteToDrawRect) { - SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - - DisplayListBuilder builder; - builder.DrawPath(SkPath::Rect(rect), DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.DrawRect(rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, DrawOvalPathPromoteToDrawOval) { - SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - - DisplayListBuilder builder; - builder.DrawPath(SkPath::Oval(rect), DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.DrawOval(rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, DrawRRectPathPromoteToDrawRRect) { - SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRRect rrect = SkRRect::MakeRectXY(rect, 2.0f, 2.0f); - - DisplayListBuilder builder; - builder.DrawPath(SkPath::RRect(rrect), DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.DrawRRect(rrect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, DrawRectRRectPathPromoteToDrawRect) { - SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRRect rrect = SkRRect::MakeRect(rect); - - DisplayListBuilder builder; - builder.DrawPath(SkPath::RRect(rrect), DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.DrawRect(rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, DrawOvalRRectPathPromoteToDrawOval) { - SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRRect rrect = SkRRect::MakeOval(rect); - - DisplayListBuilder builder; - builder.DrawPath(SkPath::RRect(rrect), DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.DrawOval(rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, ClipRectRRectPromoteToClipRect) { - SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); - - DisplayListBuilder builder; - builder.ClipRRect(SkRRect::MakeRect(clip_rect), ClipOp::kIntersect, false); - // Include a rendering op in case DlBuilder ever removes unneeded clips - builder.DrawRect(draw_rect, DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.ClipRect(clip_rect, ClipOp::kIntersect, false); - expected.DrawRect(draw_rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, ClipOvalRRectPromoteToClipOval) { - SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); - - DisplayListBuilder builder; - builder.ClipRRect(SkRRect::MakeOval(clip_rect), ClipOp::kIntersect, false); - // Include a rendering op in case DlBuilder ever removes unneeded clips - builder.DrawRect(draw_rect, DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.ClipOval(clip_rect, ClipOp::kIntersect, false); - expected.DrawRect(draw_rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, ClipRectPathPromoteToClipRect) { - SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); - - DisplayListBuilder builder; - builder.ClipPath(SkPath::Rect(clip_rect), ClipOp::kIntersect, false); - // Include a rendering op in case DlBuilder ever removes unneeded clips - builder.DrawRect(draw_rect, DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.ClipRect(clip_rect, ClipOp::kIntersect, false); - expected.DrawRect(draw_rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, ClipOvalPathPromoteToClipOval) { - SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); - - DisplayListBuilder builder; - builder.ClipPath(SkPath::Oval(clip_rect), ClipOp::kIntersect, false); - // Include a rendering op in case DlBuilder ever removes unneeded clips - builder.DrawRect(draw_rect, DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.ClipOval(clip_rect, ClipOp::kIntersect, false); - expected.DrawRect(draw_rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, ClipRRectPathPromoteToClipRRect) { - SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRRect clip_rrect = SkRRect::MakeRectXY(clip_rect, 2.0f, 2.0f); - SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); - - DisplayListBuilder builder; - builder.ClipPath(SkPath::RRect(clip_rrect), ClipOp::kIntersect, false); - // Include a rendering op in case DlBuilder ever removes unneeded clips - builder.DrawRect(draw_rect, DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.ClipRRect(clip_rrect, ClipOp::kIntersect, false); - expected.DrawRect(draw_rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, ClipRectRRectPathPromoteToClipRect) { - SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRRect clip_rrect = SkRRect::MakeRect(clip_rect); - SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); - - DisplayListBuilder builder; - builder.ClipPath(SkPath::RRect(clip_rrect), ClipOp::kIntersect, false); - // Include a rendering op in case DlBuilder ever removes unneeded clips - builder.DrawRect(draw_rect, DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.ClipRect(clip_rect, ClipOp::kIntersect, false); - expected.DrawRect(draw_rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - -TEST_F(DisplayListTest, ClipOvalRRectPathPromoteToClipOval) { - SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - SkRRect clip_rrect = SkRRect::MakeOval(clip_rect); - SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); - - DisplayListBuilder builder; - builder.ClipPath(SkPath::RRect(clip_rrect), ClipOp::kIntersect, false); - // Include a rendering op in case DlBuilder ever removes unneeded clips - builder.DrawRect(draw_rect, DlPaint()); - auto dl = builder.Build(); - - DisplayListBuilder expected; - expected.ClipOval(clip_rect, ClipOp::kIntersect, false); - expected.DrawRect(draw_rect, DlPaint()); - auto expect_dl = expected.Build(); - - DisplayListsEQ_Verbose(dl, expect_dl); -} - } // namespace testing } // namespace flutter diff --git a/display_list/dl_builder.cc b/display_list/dl_builder.cc index 9147661de26f1..98772c0d7a3ab 100644 --- a/display_list/dl_builder.cc +++ b/display_list/dl_builder.cc @@ -963,50 +963,14 @@ void DisplayListBuilder::ClipRect(const SkRect& rect, break; } } -void DisplayListBuilder::ClipOval(const SkRect& bounds, - ClipOp clip_op, - bool is_aa) { - if (!bounds.isFinite()) { - return; - } - if (current_info().is_nop) { - return; - } - if (current_info().has_valid_clip && - clip_op == DlCanvas::ClipOp::kIntersect && - layer_local_state().oval_covers_cull(bounds)) { - return; - } - global_state().clipOval(bounds, clip_op, is_aa); - layer_local_state().clipOval(bounds, clip_op, is_aa); - if (global_state().is_cull_rect_empty() || - layer_local_state().is_cull_rect_empty()) { - current_info().is_nop = true; - return; - } - current_info().has_valid_clip = true; - checkForDeferredSave(); - switch (clip_op) { - case ClipOp::kIntersect: - Push(0, bounds, is_aa); - break; - case ClipOp::kDifference: - Push(0, bounds, is_aa); - break; - } -} void DisplayListBuilder::ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { - if (current_info().is_nop) { - return; - } if (rrect.isRect()) { clipRect(rrect.rect(), clip_op, is_aa); return; } - if (rrect.isOval()) { - clipOval(rrect.rect(), clip_op, is_aa); + if (current_info().is_nop) { return; } if (current_info().has_valid_clip && @@ -1044,11 +1008,12 @@ void DisplayListBuilder::ClipPath(const SkPath& path, this->clipRect(rect, clip_op, is_aa); return; } + SkRRect rrect; if (path.isOval(&rect)) { - this->clipOval(rect, clip_op, is_aa); + rrect.setOval(rect); + this->clipRRect(rrect, clip_op, is_aa); return; } - SkRRect rrect; if (path.isRRect(&rrect)) { this->clipRRect(rrect, clip_op, is_aa); return; @@ -1223,24 +1188,6 @@ void DisplayListBuilder::DrawDRRect(const SkRRect& outer, drawDRRect(outer, inner); } void DisplayListBuilder::drawPath(const SkPath& path) { - { - SkRect rect; - if (path.isRect(&rect)) { - drawRect(rect); - return; - } - if (path.isOval(&rect)) { - drawOval(rect); - return; - } - } - { - SkRRect rrect; - if (path.isRRect(&rrect)) { - drawRRect(rrect); - return; - } - } DisplayListAttributeFlags flags = kDrawPathFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect) { diff --git a/display_list/dl_builder.h b/display_list/dl_builder.h index dc75e2d37f6af..b1a458f68eec9 100644 --- a/display_list/dl_builder.h +++ b/display_list/dl_builder.h @@ -117,10 +117,6 @@ class DisplayListBuilder final : public virtual DlCanvas, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) override; // |DlCanvas| - void ClipOval(const SkRect& bounds, - ClipOp clip_op = ClipOp::kIntersect, - bool is_aa = false) override; - // |DlCanvas| void ClipRRect(const SkRRect& rrect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) override; @@ -404,10 +400,6 @@ class DisplayListBuilder final : public virtual DlCanvas, ClipRect(rect, clip_op, is_aa); } // |DlOpReceiver| - void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override { - ClipOval(bounds, clip_op, is_aa); - } - // |DlOpReceiver| void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override { ClipRRect(rrect, clip_op, is_aa); } diff --git a/display_list/dl_canvas.h b/display_list/dl_canvas.h index 8fa4ad923f307..ab505777aeae2 100644 --- a/display_list/dl_canvas.h +++ b/display_list/dl_canvas.h @@ -105,9 +105,6 @@ class DlCanvas { virtual void ClipRect(const SkRect& rect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) = 0; - virtual void ClipOval(const SkRect& bounds, - ClipOp clip_op = ClipOp::kIntersect, - bool is_aa = false) = 0; virtual void ClipRRect(const SkRRect& rrect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) = 0; diff --git a/display_list/dl_op_receiver.h b/display_list/dl_op_receiver.h index dc85e379e4176..8de5dae62c4d7 100644 --- a/display_list/dl_op_receiver.h +++ b/display_list/dl_op_receiver.h @@ -328,7 +328,6 @@ class DlOpReceiver { virtual void transformReset() = 0; virtual void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) = 0; - virtual void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) = 0; virtual void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) = 0; virtual void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) = 0; diff --git a/display_list/dl_op_records.h b/display_list/dl_op_records.h index aeb0379e2371f..3ad6eebe8fc54 100644 --- a/display_list/dl_op_records.h +++ b/display_list/dl_op_records.h @@ -566,11 +566,11 @@ struct TransformResetOp final : TransformClipOpBase { // the header, but the Windows compiler keeps wanting to expand that // packing into more bytes than needed (even when they are declared as // packed bit fields!) -#define DEFINE_CLIP_SHAPE_OP(shapename, shapetype, clipop) \ - struct Clip##clipop##shapename##Op final : TransformClipOpBase { \ - static constexpr auto kType = DisplayListOpType::kClip##clipop##shapename; \ +#define DEFINE_CLIP_SHAPE_OP(shapetype, clipop) \ + struct Clip##clipop##shapetype##Op final : TransformClipOpBase { \ + static constexpr auto kType = DisplayListOpType::kClip##clipop##shapetype; \ \ - Clip##clipop##shapename##Op(Sk##shapetype shape, bool is_aa) \ + Clip##clipop##shapetype##Op(Sk##shapetype shape, bool is_aa) \ : is_aa(is_aa), shape(shape) {} \ \ const bool is_aa; \ @@ -578,17 +578,15 @@ struct TransformResetOp final : TransformClipOpBase { \ void dispatch(DispatchContext& ctx) const { \ if (op_needed(ctx)) { \ - ctx.receiver.clip##shapename(shape, DlCanvas::ClipOp::k##clipop, \ + ctx.receiver.clip##shapetype(shape, DlCanvas::ClipOp::k##clipop, \ is_aa); \ } \ } \ }; -DEFINE_CLIP_SHAPE_OP(Rect, Rect, Intersect) -DEFINE_CLIP_SHAPE_OP(Oval, Rect, Intersect) -DEFINE_CLIP_SHAPE_OP(RRect, RRect, Intersect) -DEFINE_CLIP_SHAPE_OP(Rect, Rect, Difference) -DEFINE_CLIP_SHAPE_OP(Oval, Rect, Difference) -DEFINE_CLIP_SHAPE_OP(RRect, RRect, Difference) +DEFINE_CLIP_SHAPE_OP(Rect, Intersect) +DEFINE_CLIP_SHAPE_OP(RRect, Intersect) +DEFINE_CLIP_SHAPE_OP(Rect, Difference) +DEFINE_CLIP_SHAPE_OP(RRect, Difference) #undef DEFINE_CLIP_SHAPE_OP #define DEFINE_CLIP_PATH_OP(clipop) \ diff --git a/display_list/skia/dl_sk_canvas.cc b/display_list/skia/dl_sk_canvas.cc index 235b654f41bca..a7334f303ec4b 100644 --- a/display_list/skia/dl_sk_canvas.cc +++ b/display_list/skia/dl_sk_canvas.cc @@ -153,12 +153,6 @@ void DlSkCanvasAdapter::ClipRect(const SkRect& rect, delegate_->clipRect(rect, ToSk(clip_op), is_aa); } -void DlSkCanvasAdapter::ClipOval(const SkRect& bounds, - ClipOp clip_op, - bool is_aa) { - delegate_->clipRRect(SkRRect::MakeOval(bounds), ToSk(clip_op), is_aa); -} - void DlSkCanvasAdapter::ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/display_list/skia/dl_sk_canvas.h b/display_list/skia/dl_sk_canvas.h index 5ceebe561ef6b..c61f3f465455e 100644 --- a/display_list/skia/dl_sk_canvas.h +++ b/display_list/skia/dl_sk_canvas.h @@ -72,7 +72,6 @@ class DlSkCanvasAdapter final : public virtual DlCanvas { SkMatrix GetTransform() const override; void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; - void ClipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/display_list/skia/dl_sk_dispatcher.cc b/display_list/skia/dl_sk_dispatcher.cc index 819860d3fb184..84c7115fb5fa4 100644 --- a/display_list/skia/dl_sk_dispatcher.cc +++ b/display_list/skia/dl_sk_dispatcher.cc @@ -122,11 +122,6 @@ void DlSkCanvasDispatcher::clipRect(const SkRect& rect, bool is_aa) { canvas_->clipRect(rect, ToSk(clip_op), is_aa); } -void DlSkCanvasDispatcher::clipOval(const SkRect& bounds, - ClipOp clip_op, - bool is_aa) { - canvas_->clipRRect(SkRRect::MakeOval(bounds), ToSk(clip_op), is_aa); -} void DlSkCanvasDispatcher::clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/display_list/skia/dl_sk_dispatcher.h b/display_list/skia/dl_sk_dispatcher.h index 384f722633677..ef15f8152e736 100644 --- a/display_list/skia/dl_sk_dispatcher.h +++ b/display_list/skia/dl_sk_dispatcher.h @@ -51,7 +51,6 @@ class DlSkCanvasDispatcher : public virtual DlOpReceiver, void transformReset() override; void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; - void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/display_list/testing/dl_rendering_unittests.cc b/display_list/testing/dl_rendering_unittests.cc index 1368f3e921fbe..89102029e175b 100644 --- a/display_list/testing/dl_rendering_unittests.cc +++ b/display_list/testing/dl_rendering_unittests.cc @@ -2073,39 +2073,6 @@ class CanvasCompareTester { ctx.canvas->ClipRect(r_clip, ClipOp::kDifference, false); }) .with_diff_clip()); - // Skia lacks clipOval and requires us to make an oval SkRRect - SkRRect rr_oval_clip = SkRRect::MakeOval(r_clip); - RenderWith(testP, env, intersect_tolerance, - CaseParameters( - "Hard ClipOval", - [=](const SkSetupContext& ctx) { - ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kIntersect, - false); - }, - [=](const DlSetupContext& ctx) { - ctx.canvas->ClipOval(r_clip, ClipOp::kIntersect, false); - })); - RenderWith(testP, env, intersect_tolerance, - CaseParameters( - "AntiAlias ClipOval", - [=](const SkSetupContext& ctx) { - ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kIntersect, - true); - }, - [=](const DlSetupContext& ctx) { - ctx.canvas->ClipOval(r_clip, ClipOp::kIntersect, true); - })); - RenderWith(testP, env, diff_tolerance, - CaseParameters( - "Hard ClipOval Diff", - [=](const SkSetupContext& ctx) { - ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kDifference, - false); - }, - [=](const DlSetupContext& ctx) { - ctx.canvas->ClipOval(r_clip, ClipOp::kDifference, false); - }) - .with_diff_clip()); // This test RR clip used to use very small radii, but due to // optimizations in the HW rrect rasterization, this caused small // bulges in the corners of the RRect which were interpreted as @@ -2883,14 +2850,12 @@ TEST_F(DisplayListRendering, DrawDiagonalLines) { SkPoint p2 = SkPoint::Make(kRenderRight, kRenderBottom); SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderBottom); SkPoint p4 = SkPoint::Make(kRenderRight, kRenderTop); - // Adding some edge to edge diagonals that run through the points about - // 16 units in from the center of that edge. // Adding some edge center to edge center diagonals to better fill // out the RRect Clip so bounds checking sees less empty bounds space. - SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop + 15); - SkPoint p6 = SkPoint::Make(kRenderRight - 15, kRenderCenterY); - SkPoint p7 = SkPoint::Make(kRenderCenterX, kRenderBottom - 15); - SkPoint p8 = SkPoint::Make(kRenderLeft + 15, kRenderCenterY); + SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop); + SkPoint p6 = SkPoint::Make(kRenderRight, kRenderCenterY); + SkPoint p7 = SkPoint::Make(kRenderLeft, kRenderCenterY); + SkPoint p8 = SkPoint::Make(kRenderCenterX, kRenderBottom); CanvasCompareTester::RenderAll( // TestParameters( @@ -2915,13 +2880,9 @@ TEST_F(DisplayListRendering, DrawDiagonalLines) { .set_draw_line()); } -TEST_F(DisplayListRendering, DrawHorizontalLines) { - SkPoint p1 = SkPoint::Make(kRenderLeft, kRenderTop + 16); - SkPoint p2 = SkPoint::Make(kRenderRight, kRenderTop + 16); - SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderCenterY); - SkPoint p4 = SkPoint::Make(kRenderRight, kRenderCenterY); - SkPoint p5 = SkPoint::Make(kRenderLeft, kRenderBottom - 16); - SkPoint p6 = SkPoint::Make(kRenderRight, kRenderBottom - 16); +TEST_F(DisplayListRendering, DrawHorizontalLine) { + SkPoint p1 = SkPoint::Make(kRenderLeft, kRenderCenterY); + SkPoint p2 = SkPoint::Make(kRenderRight, kRenderCenterY); CanvasCompareTester::RenderAll( // TestParameters( @@ -2932,26 +2893,18 @@ TEST_F(DisplayListRendering, DrawHorizontalLines) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); ctx.canvas->drawLine(p1, p2, p); - ctx.canvas->drawLine(p3, p4, p); - ctx.canvas->drawLine(p5, p6, p); }, [=](const DlRenderContext& ctx) { // ctx.canvas->DrawLine(p1, p2, ctx.paint); - ctx.canvas->DrawLine(p3, p4, ctx.paint); - ctx.canvas->DrawLine(p5, p6, ctx.paint); }, kDrawHVLineFlags) .set_draw_line() .set_horizontal_line()); } -TEST_F(DisplayListRendering, DrawVerticalLines) { - SkPoint p1 = SkPoint::Make(kRenderLeft + 16, kRenderTop); - SkPoint p2 = SkPoint::Make(kRenderLeft + 16, kRenderBottom); - SkPoint p3 = SkPoint::Make(kRenderCenterX, kRenderTop); - SkPoint p4 = SkPoint::Make(kRenderCenterX, kRenderBottom); - SkPoint p5 = SkPoint::Make(kRenderRight - 16, kRenderTop); - SkPoint p6 = SkPoint::Make(kRenderRight - 16, kRenderBottom); +TEST_F(DisplayListRendering, DrawVerticalLine) { + SkPoint p1 = SkPoint::Make(kRenderCenterX, kRenderTop); + SkPoint p2 = SkPoint::Make(kRenderCenterY, kRenderBottom); CanvasCompareTester::RenderAll( // TestParameters( @@ -2962,13 +2915,9 @@ TEST_F(DisplayListRendering, DrawVerticalLines) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); ctx.canvas->drawLine(p1, p2, p); - ctx.canvas->drawLine(p3, p4, p); - ctx.canvas->drawLine(p5, p6, p); }, [=](const DlRenderContext& ctx) { // ctx.canvas->DrawLine(p1, p2, ctx.paint); - ctx.canvas->DrawLine(p3, p4, ctx.paint); - ctx.canvas->DrawLine(p5, p6, ctx.paint); }, kDrawHVLineFlags) .set_draw_line() @@ -2980,14 +2929,12 @@ TEST_F(DisplayListRendering, DrawDiagonalDashedLines) { SkPoint p2 = SkPoint::Make(kRenderRight, kRenderBottom); SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderBottom); SkPoint p4 = SkPoint::Make(kRenderRight, kRenderTop); - // Adding some edge to edge diagonals that run through the points about - // 16 units in from the center of that edge. // Adding some edge center to edge center diagonals to better fill // out the RRect Clip so bounds checking sees less empty bounds space. - SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop + 15); - SkPoint p6 = SkPoint::Make(kRenderRight - 15, kRenderCenterY); - SkPoint p7 = SkPoint::Make(kRenderCenterX, kRenderBottom - 15); - SkPoint p8 = SkPoint::Make(kRenderLeft + 15, kRenderCenterY); + SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop); + SkPoint p6 = SkPoint::Make(kRenderRight, kRenderCenterY); + SkPoint p7 = SkPoint::Make(kRenderLeft, kRenderCenterY); + SkPoint p8 = SkPoint::Make(kRenderCenterX, kRenderBottom); // Full diagonals are 100x100 which are 140 in length // Dashing them with 25 on, 5 off means that the last @@ -3008,7 +2955,7 @@ TEST_F(DisplayListRendering, DrawDiagonalDashedLines) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); SkScalar intervals[2] = {25.0f, 5.0f}; - p.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0.0f)); + p.setPathEffect(SkDashPathEffect::Make(intervals, 2.0f, 0.0f)); ctx.canvas->drawLine(p1, p2, p); ctx.canvas->drawLine(p3, p4, p); ctx.canvas->drawLine(p5, p6, p); @@ -3178,7 +3125,7 @@ TEST_F(DisplayListRendering, DrawPointsAsPoints) { const SkScalar x3 = kRenderCenterX + 0.1; const SkScalar x4 = (kRenderRight + kRenderCenterX) * 0.5; const SkScalar x5 = kRenderRight - 16; - const SkScalar x6 = kRenderRight - 1; + const SkScalar x6 = kRenderRight; const SkScalar y0 = kRenderTop; const SkScalar y1 = kRenderTop + 16; @@ -3186,7 +3133,7 @@ TEST_F(DisplayListRendering, DrawPointsAsPoints) { const SkScalar y3 = kRenderCenterY + 0.1; const SkScalar y4 = (kRenderBottom + kRenderCenterY) * 0.5; const SkScalar y5 = kRenderBottom - 16; - const SkScalar y6 = kRenderBottom - 1; + const SkScalar y6 = kRenderBottom; // clang-format off const SkPoint points[] = { @@ -3230,7 +3177,7 @@ TEST_F(DisplayListRendering, DrawPointsAsLines) { const SkScalar y0 = kRenderTop; const SkScalar y1 = kRenderTop + 16; const SkScalar y2 = kRenderBottom - 16; - const SkScalar y3 = kRenderBottom - 1; + const SkScalar y3 = kRenderBottom; // clang-format off const SkPoint points[] = { @@ -3279,12 +3226,10 @@ TEST_F(DisplayListRendering, DrawPointsAsPolygon) { SkPoint::Make(kRenderRight, kRenderBottom), SkPoint::Make(kRenderLeft, kRenderBottom), SkPoint::Make(kRenderLeft, kRenderTop), - - SkPoint::Make(kRenderCenterX, kRenderTop + 15), - SkPoint::Make(kRenderRight - 15, kRenderCenterY), - SkPoint::Make(kRenderCenterX, kRenderBottom - 15), - SkPoint::Make(kRenderLeft + 15, kRenderCenterY), - SkPoint::Make(kRenderCenterX, kRenderTop + 15), + SkPoint::Make(kRenderCenterX, kRenderTop), + SkPoint::Make(kRenderRight, kRenderCenterY), + SkPoint::Make(kRenderCenterX, kRenderBottom), + SkPoint::Make(kRenderLeft, kRenderCenterY), }; const int count1 = sizeof(points1) / sizeof(points1[0]); @@ -3785,7 +3730,7 @@ TEST_F(DisplayListRendering, DrawShadow) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 7; + const SkScalar elevation = 5; CanvasCompareTester::RenderAll( // TestParameters( @@ -3811,7 +3756,7 @@ TEST_F(DisplayListRendering, DrawShadowTransparentOccluder) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 7; + const SkScalar elevation = 5; CanvasCompareTester::RenderAll( // TestParameters( @@ -3837,7 +3782,7 @@ TEST_F(DisplayListRendering, DrawShadowDpr) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 7; + const SkScalar elevation = 5; CanvasCompareTester::RenderAll( // TestParameters( diff --git a/display_list/testing/dl_test_snippets.cc b/display_list/testing/dl_test_snippets.cc index 16c0edb5d4468..e5ad4b2f365dc 100644 --- a/display_list/testing/dl_test_snippets.cc +++ b/display_list/testing/dl_test_snippets.cc @@ -424,30 +424,6 @@ std::vector CreateAllClipOps() { r.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, false); }}, }}, - {"ClipOval", - { - {1, 24, 0, - [](DlOpReceiver& r) { - r.clipOval(kTestBounds, DlCanvas::ClipOp::kIntersect, true); - }}, - {1, 24, 0, - [](DlOpReceiver& r) { - r.clipOval(kTestBounds.makeOffset(1, 1), - DlCanvas::ClipOp::kIntersect, true); - }}, - {1, 24, 0, - [](DlOpReceiver& r) { - r.clipOval(kTestBounds, DlCanvas::ClipOp::kIntersect, false); - }}, - {1, 24, 0, - [](DlOpReceiver& r) { - r.clipOval(kTestBounds, DlCanvas::ClipOp::kDifference, true); - }}, - {1, 24, 0, - [](DlOpReceiver& r) { - r.clipOval(kTestBounds, DlCanvas::ClipOp::kDifference, false); - }}, - }}, {"ClipRRect", { {1, 64, 0, @@ -503,15 +479,10 @@ std::vector CreateAllClipOps() { [](DlOpReceiver& r) { r.clipPath(kTestPathRect, DlCanvas::ClipOp::kIntersect, true); }}, - // clipPath(oval) becomes clipOval - {1, 24, 0, - [](DlOpReceiver& r) { - r.clipPath(kTestPathOval, DlCanvas::ClipOp::kIntersect, true); - }}, - // clipPath(rrect) becomes clipRRect + // clipPath(oval) becomes clipRRect {1, 64, 0, [](DlOpReceiver& r) { - r.clipPath(kTestPathRRect, DlCanvas::ClipOp::kIntersect, true); + r.clipPath(kTestPathOval, DlCanvas::ClipOp::kIntersect, true); }}, }}, }; @@ -666,11 +637,8 @@ std::vector CreateAllRenderingOps() { {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath1); }}, {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath2); }}, {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath3); }}, - // oval and rect paths are redirected to drawRect and drawOval - {1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }}, - {1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }}, - // rrect path is redirected to drawRRect - {1, 56, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRRect); }}, + {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }}, + {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }}, }}, {"DrawArc", { diff --git a/display_list/testing/dl_test_snippets.h b/display_list/testing/dl_test_snippets.h index 733ce67364034..16d740c2fb6a0 100644 --- a/display_list/testing/dl_test_snippets.h +++ b/display_list/testing/dl_test_snippets.h @@ -183,7 +183,6 @@ static const SkRRect kTestInnerRRect = SkRRect::MakeRectXY(kTestBounds.makeInset(5, 5), 2, 2); static const SkPath kTestPathRect = SkPath::Rect(kTestBounds); static const SkPath kTestPathOval = SkPath::Oval(kTestBounds); -static const SkPath kTestPathRRect = SkPath::RRect(kTestRRect); static const SkPath kTestPath1 = SkPath::Polygon({{0, 0}, {10, 10}, {10, 0}, {0, 10}}, true); static const SkPath kTestPath2 = diff --git a/display_list/utils/dl_matrix_clip_tracker.cc b/display_list/utils/dl_matrix_clip_tracker.cc index 86f3cff46a6d9..748cf07a8385a 100644 --- a/display_list/utils/dl_matrix_clip_tracker.cc +++ b/display_list/utils/dl_matrix_clip_tracker.cc @@ -74,24 +74,6 @@ void DisplayListMatrixClipState::clipRect(const DlRect& rect, } } -void DisplayListMatrixClipState::clipOval(const DlRect& bounds, - ClipOp op, - bool is_aa) { - if (!bounds.IsFinite()) { - return; - } - switch (op) { - case DlCanvas::ClipOp::kIntersect: - adjustCullRect(bounds, op, is_aa); - break; - case DlCanvas::ClipOp::kDifference: - if (oval_covers_cull(bounds)) { - cull_rect_ = DlRect(); - } - break; - } -} - void DisplayListMatrixClipState::clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) { diff --git a/display_list/utils/dl_matrix_clip_tracker.h b/display_list/utils/dl_matrix_clip_tracker.h index 4a6198d75a3e1..59c9880bd3bd7 100644 --- a/display_list/utils/dl_matrix_clip_tracker.h +++ b/display_list/utils/dl_matrix_clip_tracker.h @@ -149,10 +149,6 @@ class DisplayListMatrixClipState { void clipRect(const SkRect& rect, ClipOp op, bool is_aa) { clipRect(ToDlRect(rect), op, is_aa); } - void clipOval(const DlRect& bounds, ClipOp op, bool is_aa); - void clipOval(const SkRect& bounds, ClipOp op, bool is_aa) { - clipRect(ToDlRect(bounds), op, is_aa); - } void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa); void clipPath(const SkPath& path, ClipOp op, bool is_aa); diff --git a/display_list/utils/dl_receiver_utils.h b/display_list/utils/dl_receiver_utils.h index bb6ce6539f653..d50cb00cba057 100644 --- a/display_list/utils/dl_receiver_utils.h +++ b/display_list/utils/dl_receiver_utils.h @@ -44,9 +44,6 @@ class IgnoreClipDispatchHelper : public virtual DlOpReceiver { void clipRect(const SkRect& rect, DlCanvas::ClipOp clip_op, bool is_aa) override {} - void clipOval(const SkRect& bounds, - DlCanvas::ClipOp clip_op, - bool is_aa) override {} void clipRRect(const SkRRect& rrect, DlCanvas::ClipOp clip_op, bool is_aa) override {} diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index 089e5259ffa5a..aaed5e44f647b 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -723,14 +723,6 @@ void DlDispatcherBase::clipRect(const SkRect& rect, ToClipOperation(clip_op)); } -// |flutter::DlOpReceiver| -void DlDispatcherBase::clipOval(const SkRect& bounds, - ClipOp clip_op, - bool is_aa) { - GetCanvas().ClipOval(skia_conversions::ToRect(bounds), - ToClipOperation(clip_op)); -} - // |flutter::DlOpReceiver| void DlDispatcherBase::clipRRect(const SkRRect& rrect, ClipOp sk_op, diff --git a/impeller/display_list/dl_dispatcher.h b/impeller/display_list/dl_dispatcher.h index 294616b748776..7349ca7e4fd84 100644 --- a/impeller/display_list/dl_dispatcher.h +++ b/impeller/display_list/dl_dispatcher.h @@ -123,9 +123,6 @@ class DlDispatcherBase : public flutter::DlOpReceiver { // |flutter::DlOpReceiver| void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; - // |flutter::DlOpReceiver| - void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; - // |flutter::DlOpReceiver| void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; diff --git a/testing/display_list_testing.cc b/testing/display_list_testing.cc index ce831ca247813..8cf84bc270242 100644 --- a/testing/display_list_testing.cc +++ b/testing/display_list_testing.cc @@ -742,14 +742,6 @@ void DisplayListStreamDispatcher::clipRect(const SkRect& rect, ClipOp clip_op, << "isaa: " << is_aa << ");" << std::endl; } -void DisplayListStreamDispatcher::clipOval(const SkRect& bounds, ClipOp clip_op, - bool is_aa) { - startl() << "clipOval(" - << bounds << ", " - << clip_op << ", " - << "isaa: " << is_aa - << ");" << std::endl; -} void DisplayListStreamDispatcher::clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/testing/display_list_testing.h b/testing/display_list_testing.h index 2ccb011dedcf0..b710e1e22af45 100644 --- a/testing/display_list_testing.h +++ b/testing/display_list_testing.h @@ -118,7 +118,6 @@ class DisplayListStreamDispatcher final : public DlOpReceiver { void transformReset() override; void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; - void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc index 03627f722fbaa..695678e23a0ee 100644 --- a/testing/mock_canvas.cc +++ b/testing/mock_canvas.cc @@ -214,13 +214,6 @@ void MockCanvas::ClipRect(const SkRect& rect, ClipOp op, bool is_aa) { state_stack_.back().clipRect(rect, op, is_aa); } -void MockCanvas::ClipOval(const SkRect& bounds, ClipOp op, bool is_aa) { - ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle; - draw_calls_.emplace_back( - DrawCall{current_layer_, ClipOvalData{bounds, op, style}}); - state_stack_.back().clipOval(bounds, op, is_aa); -} - void MockCanvas::ClipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) { ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle; draw_calls_.emplace_back( @@ -527,16 +520,6 @@ std::ostream& operator<<(std::ostream& os, return os << data.rect << " " << data.clip_op << " " << data.style; } -bool operator==(const MockCanvas::ClipOvalData& a, - const MockCanvas::ClipOvalData& b) { - return a.bounds == b.bounds && a.clip_op == b.clip_op && a.style == b.style; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::ClipOvalData& data) { - return os << data.bounds << " " << data.clip_op << " " << data.style; -} - bool operator==(const MockCanvas::ClipRRectData& a, const MockCanvas::ClipRRectData& b) { return a.rrect == b.rrect && a.clip_op == b.clip_op && a.style == b.style; diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h index 7384d5ecf578a..f15e0ec54adf2 100644 --- a/testing/mock_canvas.h +++ b/testing/mock_canvas.h @@ -114,12 +114,6 @@ class MockCanvas final : public DlCanvas { ClipEdgeStyle style; }; - struct ClipOvalData { - SkRect bounds; - ClipOp clip_op; - ClipEdgeStyle style; - }; - struct ClipRRectData { SkRRect rrect; ClipOp clip_op; @@ -151,7 +145,6 @@ class MockCanvas final : public DlCanvas { DrawDisplayListData, DrawShadowData, ClipRectData, - ClipOvalData, ClipRRectData, ClipPathData, DrawPaintData>; @@ -213,7 +206,6 @@ class MockCanvas final : public DlCanvas { SkMatrix GetTransform() const override; void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; - void ClipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; From 4da38deb71286bafb5f2523d96a3caf043df737e Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 09:20:24 -0400 Subject: [PATCH 78/88] Roll Skia from cd77153f20a8 to 23a14cccc800 (1 revision) (#53631) https://skia.googlesource.com/skia.git/+log/cd77153f20a8..23a14cccc800 2024-06-28 skia-autoroll@skia-public.iam.gserviceaccount.com Roll SK Tool from 40eb79dec2d6 to 5ae05e0e6a28 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index c13078af9595a..702b1034f5f49 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'cd77153f20a8331ee4f8a8eb1ff956fbdc441692', + 'skia_revision': '23a14cccc800ba70cc07d22c3c41d14323c0454c', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 1e183f5bd39ecbf573e192ffb2d7c30fe4f39bf3 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 11:44:20 -0400 Subject: [PATCH 79/88] Roll Skia from 23a14cccc800 to 7a09d38fa7f8 (1 revision) (#53633) https://skia.googlesource.com/skia.git/+log/23a14cccc800..7a09d38fa7f8 2024-06-28 michaelludwig@google.com [graphite] Consolidate expression/preamble generators If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 702b1034f5f49..62837d327ee92 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '23a14cccc800ba70cc07d22c3c41d14323c0454c', + 'skia_revision': '7a09d38fa7f8141c05ddfae27a4852c435222141', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 7c4d83b8341bc..944ab5a66cd41 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 7824470b0fe3d3fa2b92db248464d861 +Signature: 70e2823de19937e624e432f8f2dafd04 ==================================================================================================== LIBRARY: etc1 From 2f7e9ab274933e1ed221ad793dec85b99331426d Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 13:00:57 -0400 Subject: [PATCH 80/88] Roll Skia from 7a09d38fa7f8 to 3d5f5d546fb6 (1 revision) (#53634) https://skia.googlesource.com/skia.git/+log/7a09d38fa7f8..3d5f5d546fb6 2024-06-28 kjlubick@google.com Delete unnecessary file If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/DEPS b/DEPS index 62837d327ee92..1ce4184abfb6d 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '7a09d38fa7f8141c05ddfae27a4852c435222141', + 'skia_revision': '3d5f5d546fb65e10aad6b8f039c203a94268c98c', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 944ab5a66cd41..e9d1798220a0e 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 70e2823de19937e624e432f8f2dafd04 +Signature: 3770c19880fce84913b86fa2220cbeb9 ==================================================================================================== LIBRARY: etc1 @@ -6689,7 +6689,6 @@ ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/GrDDLTask.cpp + ../../. ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/GrDDLTask.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/GrManagedResource.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/GrPixmap.h + ../../../flutter/third_party/skia/LICENSE -ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/GrRenderTargetContext.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/GrRingBuffer.cpp + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/GrRingBuffer.h + ../../../flutter/third_party/skia/LICENSE ORIGIN: ../../../flutter/third_party/skia/src/gpu/ganesh/GrStagingBufferManager.cpp + ../../../flutter/third_party/skia/LICENSE @@ -6823,7 +6822,6 @@ FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/GrDDLTask.cpp FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/GrDDLTask.h FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/GrManagedResource.cpp FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/GrPixmap.h -FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/GrRenderTargetContext.h FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/GrRingBuffer.cpp FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/GrRingBuffer.h FILE: ../../../flutter/third_party/skia/src/gpu/ganesh/GrStagingBufferManager.cpp From aaa3198d7650051cb631fa1b9345525c2cd3ae14 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 13:50:03 -0400 Subject: [PATCH 81/88] Roll Dart SDK from 341dbaf977a3 to 89b164e3adeb (2 revisions) (#53636) https://dart.googlesource.com/sdk.git/+log/341dbaf977a3..89b164e3adeb 2024-06-28 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-315.0.dev 2024-06-28 dart-internal-merge@dart-ci-internal.iam.gserviceaccount.com Version 3.5.0-314.0.dev If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/dart-sdk-flutter-engine Please CC dart-vm-team@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 4 ++-- sky/packages/sky_engine/LICENSE | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DEPS b/DEPS index 1ce4184abfb6d..5425594dc464e 100644 --- a/DEPS +++ b/DEPS @@ -56,7 +56,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '341dbaf977a3ca3ef9261945e3c024ac5de14fc5', + 'dart_revision': '89b164e3adeb1984ae4487d2008884fa7225fab2', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py @@ -434,7 +434,7 @@ deps = { Var('dart_git') + '/mockito.git@9deddcfa4b6b6c1ecb3111891c20cc46c115569d', 'src/flutter/third_party/dart/third_party/pkg/native': - Var('dart_git') + '/native.git@fef40aebc3cf34654919e8a5785b6c50b3ea445c', + Var('dart_git') + '/native.git@fcc783c1d2777555616dfc850f131878ea5d88a9', 'src/flutter/third_party/dart/third_party/pkg/package_config': Var('dart_git') + '/package_config.git@903a0e528f91aef90821c8f5eaafbc1ae27198ab', diff --git a/sky/packages/sky_engine/LICENSE b/sky/packages/sky_engine/LICENSE index 9bbb5c41d1b76..ba4e0d889e8fd 100644 --- a/sky/packages/sky_engine/LICENSE +++ b/sky/packages/sky_engine/LICENSE @@ -31897,7 +31897,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/341dbaf977a3ca3ef9261945e3c024ac5de14fc5 +You may obtain a copy of this library's Source Code Form from: https://dart.googlesource.com/sdk/+/89b164e3adeb1984ae4487d2008884fa7225fab2 /third_party/fallback_root_certificates/ -------------------------------------------------------------------------------- From f65328a433ef8b0214ca87ce8c786609a116dd52 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 14:15:23 -0400 Subject: [PATCH 82/88] Roll Skia from 3d5f5d546fb6 to fc6f00bfacb5 (1 revision) (#53637) https://skia.googlesource.com/skia.git/+log/3d5f5d546fb6..fc6f00bfacb5 2024-06-28 sunnyps@chromium.org graphite: Expose maxTextureSize on Recorder If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 5425594dc464e..4bb3ba7b4ef70 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '3d5f5d546fb65e10aad6b8f039c203a94268c98c', + 'skia_revision': 'fc6f00bfacb524fa15cf0db51897c40dd99e6561', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index e9d1798220a0e..ac9bd447f0a1f 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 3770c19880fce84913b86fa2220cbeb9 +Signature: 7325819d0adc30dfaf305f90c86918bf ==================================================================================================== LIBRARY: etc1 From f828363d03ff4e6bbce2b6b5e71da8ac73c1c345 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Fri, 28 Jun 2024 16:40:00 -0400 Subject: [PATCH 83/88] Roll Skia from fc6f00bfacb5 to 1ad84eb8e94f (2 revisions) (#53641) https://skia.googlesource.com/skia.git/+log/fc6f00bfacb5..1ad84eb8e94f 2024-06-28 jvanverth@google.com [graphite] Fix color text rendering, part 1. 2024-06-28 kjlubick@google.com Add jobs for Galaxy S24 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 4bb3ba7b4ef70..c12aef80cb9dc 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'fc6f00bfacb524fa15cf0db51897c40dd99e6561', + 'skia_revision': '1ad84eb8e94f1bab286b616ae8907c7a18e20ed9', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index ac9bd447f0a1f..4f2bc67dedb8e 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 7325819d0adc30dfaf305f90c86918bf +Signature: 527540e9772de0bb00747b53dc9e26ed ==================================================================================================== LIBRARY: etc1 From b6f6e1ddcbb7a22b9b85624412138ecf0c3e0fa6 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 28 Jun 2024 13:42:07 -0700 Subject: [PATCH 84/88] [Impeller] experimental canvas bdf support. (#53597) Almost working bdf for experimentcal canvas. Currently there are some problems with the clip depth, and positioning of the backdrop filter. I think I am not taking the blur transform into account at the very least. FYI @bdero --- impeller/aiks/experimental_canvas.cc | 299 ++++++++++++++++++---- impeller/aiks/experimental_canvas.h | 16 +- impeller/aiks/image_filter.h | 4 + impeller/display_list/dl_dispatcher.cc | 10 +- impeller/display_list/dl_playground.cc | 4 +- impeller/entity/entity_pass_clip_stack.cc | 1 - shell/gpu/gpu_surface_metal_impeller.mm | 4 +- 7 files changed, 273 insertions(+), 65 deletions(-) diff --git a/impeller/aiks/experimental_canvas.cc b/impeller/aiks/experimental_canvas.cc index 6d6565e92da7d..7ed3ed1bb38b1 100644 --- a/impeller/aiks/experimental_canvas.cc +++ b/impeller/aiks/experimental_canvas.cc @@ -84,8 +84,7 @@ static std::unique_ptr CreateRenderTarget( .load_action = LoadAction::kDontCare, .store_action = StoreAction::kMultisampleResolve, .clear_color = clear_color}, - /*stencil_attachment_config=*/ - kDefaultStencilConfig); + /*stencil_attachment_config=*/kDefaultStencilConfig); } else { target = renderer.GetRenderTargetCache()->CreateOffscreen( *context, // context @@ -98,7 +97,7 @@ static std::unique_ptr CreateRenderTarget( .store_action = StoreAction::kDontCare, .clear_color = clear_color, }, // color_attachment_config - kDefaultStencilConfig // stencil_attachment_config + kDefaultStencilConfig // ); } @@ -172,21 +171,23 @@ void ExperimentalCanvas::SetupRenderPass() { // a second save layer with the same dimensions as the onscreen. When // rendering is completed, we must blit this saveLayer to the onscreen. if (requires_readback_) { - entity_pass_targets_.push_back(CreateRenderTarget( - renderer_, color0.texture->GetSize(), /*mip_count=*/1, - /*clear_color=*/Color::BlackTransparent())); + auto entity_pass_target = CreateRenderTarget( + renderer_, // + color0.texture->GetSize(), // + // Note: this is incorrect, we also need to know what kind of filter. + /*mip_count=*/4, // + /*clear_color=*/Color::BlackTransparent()); + render_passes_.push_back( + LazyRenderingConfig(renderer_, std::move(entity_pass_target))); } else { - entity_pass_targets_.push_back(std::make_unique( - render_target_, - renderer_.GetDeviceCapabilities().SupportsReadFromResolve(), - renderer_.GetDeviceCapabilities().SupportsImplicitResolvingMSAA())); + auto entity_pass_target = std::make_unique( + render_target_, // + renderer_.GetDeviceCapabilities().SupportsReadFromResolve(), // + renderer_.GetDeviceCapabilities().SupportsImplicitResolvingMSAA() // + ); + render_passes_.push_back( + LazyRenderingConfig(renderer_, std::move(entity_pass_target))); } - - auto inline_pass = std::make_unique( - renderer_, *entity_pass_targets_.back(), 0); - inline_pass_contexts_.emplace_back(std::move(inline_pass)); - auto result = inline_pass_contexts_.back()->GetRenderPass(0u); - render_passes_.push_back(result.pass); } void ExperimentalCanvas::Save(uint32_t total_content_depth) { @@ -210,16 +211,148 @@ void ExperimentalCanvas::SaveLayer( ContentBoundsPromise bounds_promise, uint32_t total_content_depth, bool can_distribute_opacity) { + // Can we always guarantee that we get a bounds? Does a lack of bounds + // indicate something? + if (!bounds.has_value()) { + bounds = Rect::MakeSize(render_target_.GetRenderTargetSize()); + } + + // SaveLayer is a no-op, depending on the bounds promise. Should/Can DL elide + // this? + if (bounds->IsEmpty()) { + Save(total_content_depth); + return; + } + + // The maximum coverage of the subpass. Subpasses textures should never + // extend outside the parent pass texture or the current clip coverage. + Rect coverage_limit = Rect::MakeOriginSize( + GetGlobalPassPosition(), + Size(render_passes_.back().inline_pass_context->GetTexture()->GetSize())); + + // BDF No-op. need to do some precomputation to ensure this is fully skipped. + if (backdrop_filter) { + if (!clip_coverage_stack_.HasCoverage()) { + Save(total_content_depth); + return; + } + auto maybe_clip_coverage = clip_coverage_stack_.CurrentClipCoverage(); + if (!maybe_clip_coverage.has_value()) { + Save(total_content_depth); + return; + } + auto clip_coverage = maybe_clip_coverage.value(); + if (clip_coverage.IsEmpty() || + !coverage_limit.IntersectsWithRect(clip_coverage)) { + Save(total_content_depth); + return; + } + } + if (can_distribute_opacity && !backdrop_filter && Paint::CanApplyOpacityPeephole(paint)) { Save(total_content_depth); transform_stack_.back().distributed_opacity *= paint.color.alpha; return; } - // Can we always guarantee that we get a bounds? Does a lack of bounds - // indicate something? - if (!bounds.has_value()) { - bounds = Rect::MakeSize(render_target_.GetRenderTargetSize()); + + // Backdrop filter state, ignored if there is no BDF. + std::shared_ptr backdrop_filter_contents; + Point local_position = {0, 0}; + if (backdrop_filter) { + auto current_clip_coverage = clip_coverage_stack_.CurrentClipCoverage(); + if (current_clip_coverage.has_value()) { + local_position = + current_clip_coverage->GetOrigin() - GetGlobalPassPosition(); + } + EntityPass::BackdropFilterProc backdrop_filter_proc = + [backdrop_filter = backdrop_filter->Clone()]( + const FilterInput::Ref& input, const Matrix& effect_transform, + Entity::RenderingMode rendering_mode) { + auto filter = backdrop_filter->WrapInput(input); + filter->SetEffectTransform(effect_transform); + filter->SetRenderingMode(rendering_mode); + return filter; + }; + + auto rendering_config = std::move(render_passes_.back()); + render_passes_.pop_back(); + + // If the very first thing we render in this EntityPass is a subpass that + // happens to have a backdrop filter, than that backdrop filter will end + // may wind up sampling from the raw, uncleared texture that came straight + // out of the texture cache. By calling `pass_context.GetRenderPass` here, + // we force the texture to pass through at least one RenderPass with the + // correct clear configuration before any sampling occurs. + rendering_config.inline_pass_context->GetRenderPass(0); + + ISize restore_size = + rendering_config.inline_pass_context->GetTexture()->GetSize(); + + std::shared_ptr input_texture = + rendering_config.entity_pass_target->Flip( + *renderer_.GetContext()->GetResourceAllocator()); + + backdrop_filter_contents = backdrop_filter_proc( + FilterInput::Make(std::move(input_texture)), + transform_stack_.back().transform.Basis(), + // When the subpass has a translation that means the math with + // the snapshot has to be different. + transform_stack_.back().transform.HasTranslation() + ? Entity::RenderingMode::kSubpassPrependSnapshotTransform + : Entity::RenderingMode::kSubpassAppendSnapshotTransform); + + // The subpass will need to read from the current pass texture when + // rendering the backdrop, so if there's an active pass, end it prior to + // rendering the subpass. + rendering_config.inline_pass_context->EndPass(); + + // Create a new render pass that the backdrop filter contents will be + // restored to in order to continue rendering. + render_passes_.push_back(LazyRenderingConfig( + renderer_, std::move(rendering_config.entity_pass_target))); + // Eagerly restore the BDF contents. + + // If the pass context returns a backdrop texture, we need to draw it to the + // current pass. We do this because it's faster and takes significantly less + // memory than storing/loading large MSAA textures. Also, it's not possible + // to blit the non-MSAA resolve texture of the previous pass to MSAA + // textures (let alone a transient one). + Rect size_rect = Rect::MakeSize(restore_size); + auto msaa_backdrop_contents = TextureContents::MakeRect(size_rect); + msaa_backdrop_contents->SetStencilEnabled(false); + msaa_backdrop_contents->SetLabel("MSAA backdrop"); + msaa_backdrop_contents->SetSourceRect(size_rect); + msaa_backdrop_contents->SetTexture( + rendering_config.inline_pass_context->GetTexture()); + + Entity msaa_backdrop_entity; + msaa_backdrop_entity.SetContents(std::move(msaa_backdrop_contents)); + msaa_backdrop_entity.SetBlendMode(BlendMode::kSource); + msaa_backdrop_entity.SetClipDepth(std::numeric_limits::max()); + if (!msaa_backdrop_entity.Render(renderer_, + *render_passes_.back() + .inline_pass_context->GetRenderPass(0) + .pass)) { + VALIDATION_LOG << "Failed to render MSAA backdrop filter entity."; + return; + } + + // Restore any clips that were recorded before the backdrop filter was + // applied. + auto& replay_entities = clip_coverage_stack_.GetReplayEntities(); + for (const auto& replay : replay_entities) { + SetClipScissor( + clip_coverage_stack_.CurrentClipCoverage(), + *render_passes_.back().inline_pass_context->GetRenderPass(0).pass, + GetGlobalPassPosition()); + if (!replay.entity.Render(renderer_, + *render_passes_.back() + .inline_pass_context->GetRenderPass(0) + .pass)) { + VALIDATION_LOG << "Failed to render entity for clip restore."; + } + } } // When applying a save layer, absorb any pending distributed opacity. @@ -227,13 +360,25 @@ void ExperimentalCanvas::SaveLayer( paint_copy.color.alpha *= transform_stack_.back().distributed_opacity; transform_stack_.back().distributed_opacity = 1.0; + // Backdrop Filter must expand bounds to at least the clip stack, otherwise + // the coverage of the parent render pass. Rect subpass_coverage = bounds->TransformBounds(GetCurrentTransform()); - auto target = - CreateRenderTarget(renderer_, - ISize::MakeWH(subpass_coverage.GetSize().width, - subpass_coverage.GetSize().height), - 1u, Color::BlackTransparent()); - entity_pass_targets_.push_back(std::move(target)); + if (backdrop_filter_contents) { + FML_CHECK(clip_coverage_stack_.HasCoverage()); + // We should never hit this case as we check the intersection above. + // NOLINTBEGIN(bugprone-unchecked-optional-access) + subpass_coverage = + coverage_limit + .Intersection(clip_coverage_stack_.CurrentClipCoverage().value()) + .value(); + // NOLINTEND(bugprone-unchecked-optional-access) + } + + render_passes_.push_back(LazyRenderingConfig( + renderer_, // + CreateRenderTarget(renderer_, // + ISize(subpass_coverage.GetSize()), // + 1u, Color::BlackTransparent()))); save_layer_state_.push_back(SaveLayerState{paint_copy, subpass_coverage}); CanvasStackEntry entry; @@ -247,19 +392,25 @@ void ExperimentalCanvas::SaveLayer( entry.rendering_mode = Entity::RenderingMode::kSubpassAppendSnapshotTransform; transform_stack_.emplace_back(entry); - auto inline_pass = std::make_unique( - renderer_, *entity_pass_targets_.back(), 0); - inline_pass_contexts_.emplace_back(std::move(inline_pass)); - - auto result = inline_pass_contexts_.back()->GetRenderPass(0u); - render_passes_.push_back(result.pass); - // Start non-collapsed subpasses with a fresh clip coverage stack limited by // the subpass coverage. This is important because image filters applied to // save layers may transform the subpass texture after it's rendered, // causing parent clip coverage to get misaligned with the actual area that // the subpass will affect in the parent pass. clip_coverage_stack_.PushSubpass(subpass_coverage, GetClipHeight()); + + if (backdrop_filter_contents) { + // Render the backdrop entity. + Entity backdrop_entity; + backdrop_entity.SetContents(std::move(backdrop_filter_contents)); + backdrop_entity.SetTransform( + Matrix::MakeTranslation(Vector3(-local_position))); + backdrop_entity.SetClipDepth(std::numeric_limits::max()); + + backdrop_entity.Render( + renderer_, + *render_passes_.back().inline_pass_context->GetRenderPass(0).pass); + } } bool ExperimentalCanvas::Restore() { @@ -289,26 +440,44 @@ bool ExperimentalCanvas::Restore() { Entity::RenderingMode::kSubpassAppendSnapshotTransform || transform_stack_.back().rendering_mode == Entity::RenderingMode::kSubpassPrependSnapshotTransform) { - auto inline_pass = std::move(inline_pass_contexts_.back()); + auto lazy_render_pass = std::move(render_passes_.back()); + render_passes_.pop_back(); + // Force the render pass to be constructed if it never was. + lazy_render_pass.inline_pass_context->GetRenderPass(0); SaveLayerState save_layer_state = save_layer_state_.back(); save_layer_state_.pop_back(); std::shared_ptr contents = PaintPassDelegate(save_layer_state.paint) - .CreateContentsForSubpassTarget(inline_pass->GetTexture(), - transform_stack_.back().transform); - - inline_pass->EndPass(); - render_passes_.pop_back(); - inline_pass_contexts_.pop_back(); + .CreateContentsForSubpassTarget( + lazy_render_pass.inline_pass_context->GetTexture(), + transform_stack_.back().transform); + + lazy_render_pass.inline_pass_context->EndPass(); + + // Round the subpass texture position for pixel alignment with the parent + // pass render target. By default, we draw subpass textures with nearest + // sampling, so aligning here is important for avoiding visual nearest + // sampling errors caused by limited floating point precision when + // straddling a half pixel boundary. + // + // We do this in lieu of expanding/rounding out the subpass coverage in + // order to keep the bounds wrapping consistently tight around subpass + // elements. Which is necessary to avoid intense flickering in cases + // where a subpass texture has a large blur filter with clamp sampling. + // + // See also this bug: https://github.com/flutter/flutter/issues/144213 + Point subpass_texture_position = + (save_layer_state.coverage.GetOrigin() - GetGlobalPassPosition()) + .Round(); Entity element_entity; element_entity.SetClipDepth(++current_depth_); element_entity.SetContents(std::move(contents)); element_entity.SetBlendMode(save_layer_state.paint.blend_mode); - element_entity.SetTransform(Matrix::MakeTranslation( - Vector3(save_layer_state.coverage.GetOrigin()))); + element_entity.SetTransform( + Matrix::MakeTranslation(Vector3(subpass_texture_position))); if (element_entity.GetBlendMode() > Entity::kLastPipelineBlendMode) { if (renderer_.GetDeviceCapabilities().SupportsFramebufferFetch()) { @@ -319,7 +488,10 @@ bool ExperimentalCanvas::Restore() { } } - element_entity.Render(renderer_, *render_passes_.back()); + element_entity.Render( + renderer_, // + *render_passes_.back().inline_pass_context->GetRenderPass(0).pass // + ); clip_coverage_stack_.PopSubpass(); transform_stack_.pop_back(); @@ -364,15 +536,20 @@ bool ExperimentalCanvas::Restore() { if (clip_state_result.clip_did_change) { // We only need to update the pass scissor if the clip state has changed. - SetClipScissor(clip_coverage_stack_.CurrentClipCoverage(), - *render_passes_.back(), GetGlobalPassPosition()); + SetClipScissor( + clip_coverage_stack_.CurrentClipCoverage(), // + *render_passes_.back().inline_pass_context->GetRenderPass(0).pass, // + GetGlobalPassPosition() // + ); } if (!clip_state_result.should_render) { return true; } - entity.Render(renderer_, *render_passes_.back()); + entity.Render( + renderer_, + *render_passes_.back().inline_pass_context->GetRenderPass(0).pass); } return true; @@ -441,7 +618,16 @@ void ExperimentalCanvas::AddRenderEntityToCurrentPass(Entity entity, } } - entity.Render(renderer_, *render_passes_.back()); + InlinePassContext::RenderPassResult result = + render_passes_.back().inline_pass_context->GetRenderPass(0); + if (!result.pass) { + // Failure to produce a render pass should be explained by specific errors + // in `InlinePassContext::GetRenderPass()`, so avoid log spam and don't + // append a validation log here. + return; + } + + entity.Render(renderer_, *result.pass); } void ExperimentalCanvas::AddClipEntityToCurrentPass(Entity entity) { @@ -482,21 +668,27 @@ void ExperimentalCanvas::AddClipEntityToCurrentPass(Entity entity) { if (clip_state_result.clip_did_change) { // We only need to update the pass scissor if the clip state has changed. - SetClipScissor(clip_coverage_stack_.CurrentClipCoverage(), - *render_passes_.back(), GetGlobalPassPosition()); + SetClipScissor( + clip_coverage_stack_.CurrentClipCoverage(), + *render_passes_.back().inline_pass_context->GetRenderPass(0).pass, + GetGlobalPassPosition()); } if (!clip_state_result.should_render) { return; } - entity.Render(renderer_, *render_passes_.back()); + entity.Render( + renderer_, + *render_passes_.back().inline_pass_context->GetRenderPass(0).pass); } bool ExperimentalCanvas::BlitToOnscreen() { auto command_buffer = renderer_.GetContext()->CreateCommandBuffer(); command_buffer->SetLabel("EntityPass Root Command Buffer"); - auto offscreen_target = entity_pass_targets_.back()->GetRenderTarget(); + auto offscreen_target = render_passes_.back() + .inline_pass_context->GetPassTarget() + .GetRenderTarget(); if (renderer_.GetContext() ->GetCapabilities() @@ -551,8 +743,8 @@ bool ExperimentalCanvas::BlitToOnscreen() { } void ExperimentalCanvas::EndReplay() { - FML_DCHECK(inline_pass_contexts_.size() == 1u); - inline_pass_contexts_.back()->EndPass(); + FML_DCHECK(render_passes_.size() == 1u); + render_passes_.back().inline_pass_context->EndPass(); // If requires_readback_ was true, then we rendered to an offscreen texture // instead of to the onscreen provided in the render target. Now we need to @@ -562,7 +754,6 @@ void ExperimentalCanvas::EndReplay() { } render_passes_.clear(); - inline_pass_contexts_.clear(); renderer_.GetRenderTargetCache()->End(); Reset(); diff --git a/impeller/aiks/experimental_canvas.h b/impeller/aiks/experimental_canvas.h index 4595207dda723..64264e0681c4c 100644 --- a/impeller/aiks/experimental_canvas.h +++ b/impeller/aiks/experimental_canvas.h @@ -18,6 +18,18 @@ namespace impeller { +struct LazyRenderingConfig { + std::unique_ptr entity_pass_target; + std::unique_ptr inline_pass_context; + + LazyRenderingConfig(ContentContext& renderer, + std::unique_ptr p_entity_pass_target) + : entity_pass_target(std::move(p_entity_pass_target)) { + inline_pass_context = + std::make_unique(renderer, *entity_pass_target, 0); + } +}; + /// This Canvas attempts to translate from display lists to draw calls directly. /// /// It's not fully implemented yet but if successful it will be replacing the @@ -78,10 +90,8 @@ class ExperimentalCanvas : public Canvas { RenderTarget& render_target_; const bool requires_readback_; EntityPassClipStack clip_coverage_stack_; - std::vector> inline_pass_contexts_; - std::vector> entity_pass_targets_; + std::vector render_passes_; std::vector save_layer_state_; - std::vector> render_passes_; void SetupRenderPass(); diff --git a/impeller/aiks/image_filter.h b/impeller/aiks/image_filter.h index 9d72c14d1a522..23911cad878d0 100644 --- a/impeller/aiks/image_filter.h +++ b/impeller/aiks/image_filter.h @@ -87,6 +87,8 @@ class ImageFilter { virtual std::shared_ptr Clone() const = 0; virtual void Visit(ImageFilterVisitor& visitor) = 0; + + virtual int GetRequiredMipCount() const { return 1; } }; /******************************************************************************* @@ -112,6 +114,8 @@ class BlurImageFilter : public ImageFilter { // |ImageFilter| void Visit(ImageFilterVisitor& visitor) override { visitor.Visit(*this); } + int GetRequiredMipCount() const override { return 4; } + private: Sigma sigma_x_; Sigma sigma_y_; diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index aaed5e44f647b..f1b6552b34c97 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -1313,10 +1313,12 @@ void TextFrameDispatcher::drawTextFrame( if (text_frame->HasColor()) { properties.color = paint_.color; } - renderer_.GetLazyGlyphAtlas()->AddTextFrame(*text_frame, // - matrix_.GetMaxBasisLengthXY(), // - Point(x, y), // - properties // + auto scale = + (matrix_ * Matrix::MakeTranslation(Point(x, y))).GetMaxBasisLengthXY(); + renderer_.GetLazyGlyphAtlas()->AddTextFrame(*text_frame, // + scale, // + Point(x, y), // + properties // ); } diff --git a/impeller/display_list/dl_playground.cc b/impeller/display_list/dl_playground.cc index d31526c51cec2..97779e05cefc1 100644 --- a/impeller/display_list/dl_playground.cc +++ b/impeller/display_list/dl_playground.cc @@ -56,8 +56,8 @@ bool DlPlayground::OpenPlaygroundHere(DisplayListPlaygroundCallback callback) { ExperimentalDlDispatcher impeller_dispatcher( context.GetContentContext(), render_target, - display_list->root_has_backdrop_filter(), - display_list->max_root_blend_mode(), IRect::MakeMaximum()); + list->root_has_backdrop_filter(), list->max_root_blend_mode(), + IRect::MakeMaximum()); list->Dispatch(impeller_dispatcher); impeller_dispatcher.FinishRecording(); context.GetContentContext().GetTransientsBuffer().Reset(); diff --git a/impeller/entity/entity_pass_clip_stack.cc b/impeller/entity/entity_pass_clip_stack.cc index 54a30aceef209..eab0565b3d382 100644 --- a/impeller/entity/entity_pass_clip_stack.cc +++ b/impeller/entity/entity_pass_clip_stack.cc @@ -4,7 +4,6 @@ #include "impeller/entity/entity_pass_clip_stack.h" #include "impeller/entity/contents/clip_contents.h" -#include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" namespace impeller { diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 8664aed5e7c9a..67bd3997ef96c 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -293,7 +293,9 @@ fml::MakeCopyable([aiks_context, &display_list, &cull_rect, &sk_cull_rect](impeller::RenderTarget& render_target) -> bool { impeller::ExperimentalDlDispatcher impeller_dispatcher( - aiks_context->GetContentContext(), render_target, cull_rect); + aiks_context->GetContentContext(), render_target, + display_list->root_has_backdrop_filter(), display_list->max_root_blend_mode(), + cull_rect); display_list->Dispatch(impeller_dispatcher, sk_cull_rect); impeller_dispatcher.FinishRecording(); aiks_context->GetContentContext().GetTransientsBuffer().Reset(); From d6ee3ab1379eee48e81cedbc92a6a1ec1a249a5f Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 28 Jun 2024 13:52:21 -0700 Subject: [PATCH 85/88] Reland [DisplayList] Add support for clipOval to leverage Impeller optimization (#53642) Reland of https://github.com/flutter/engine/pull/53622 that checks the inverse fill flag of the paths. --- display_list/display_list.h | 2 + display_list/display_list_unittests.cc | 512 ++++++++++++++++-- display_list/dl_builder.cc | 59 +- display_list/dl_builder.h | 8 + display_list/dl_canvas.h | 3 + display_list/dl_op_receiver.h | 1 + display_list/dl_op_records.h | 20 +- display_list/skia/dl_sk_canvas.cc | 6 + display_list/skia/dl_sk_canvas.h | 1 + display_list/skia/dl_sk_dispatcher.cc | 5 + display_list/skia/dl_sk_dispatcher.h | 1 + .../testing/dl_rendering_unittests.cc | 105 +++- display_list/testing/dl_test_snippets.cc | 40 +- display_list/testing/dl_test_snippets.h | 1 + display_list/utils/dl_matrix_clip_tracker.cc | 18 + display_list/utils/dl_matrix_clip_tracker.h | 4 + display_list/utils/dl_receiver_utils.h | 3 + impeller/display_list/dl_dispatcher.cc | 8 + impeller/display_list/dl_dispatcher.h | 3 + testing/display_list_testing.cc | 8 + testing/display_list_testing.h | 1 + testing/mock_canvas.cc | 17 + testing/mock_canvas.h | 8 + 23 files changed, 761 insertions(+), 73 deletions(-) diff --git a/display_list/display_list.h b/display_list/display_list.h index 35c19ef9d4a0b..bb67c435cc6d7 100644 --- a/display_list/display_list.h +++ b/display_list/display_list.h @@ -98,9 +98,11 @@ namespace flutter { V(TransformReset) \ \ V(ClipIntersectRect) \ + V(ClipIntersectOval) \ V(ClipIntersectRRect) \ V(ClipIntersectPath) \ V(ClipDifferenceRect) \ + V(ClipDifferenceOval) \ V(ClipDifferenceRRect) \ V(ClipDifferencePath) \ \ diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index 635d38af7c8a9..a3d362eefad3e 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -3439,11 +3439,9 @@ TEST_F(DisplayListTest, ImpellerPathPreferenceIsHonored) { }; DisplayListBuilder builder; - builder.DrawPath(SkPath::Rect(SkRect::MakeLTRB(0, 0, 100, 100)), DlPaint()); - builder.ClipPath(SkPath::Rect(SkRect::MakeLTRB(0, 0, 100, 100)), - ClipOp::kIntersect, true); - builder.DrawShadow(SkPath::Rect(SkRect::MakeLTRB(20, 20, 80, 80)), - DlColor::kBlue(), 1.0f, true, 1.0f); + builder.DrawPath(kTestPath1, DlPaint()); + builder.ClipPath(kTestPath1, ClipOp::kIntersect, true); + builder.DrawShadow(kTestPath1, DlColor::kBlue(), 1.0f, true, 1.0f); auto display_list = builder.Build(); { @@ -4332,36 +4330,66 @@ TEST_F(DisplayListTest, DrawDisplayListForwardsBackdropFlag) { #define CLIP_EXPECTOR(name) ClipExpector name(__FILE__, __LINE__) +struct ClipExpectation { + std::variant shape; + bool is_oval; + ClipOp clip_op; + bool is_aa; + + std::string shape_name() { + switch (shape.index()) { + case 0: + return is_oval ? "SkOval" : "SkRect"; + case 1: + return "SkRRect"; + case 2: + return "SkPath"; + default: + return "Unknown"; + } + } +}; + +::std::ostream& operator<<(::std::ostream& os, const ClipExpectation& expect) { + os << "Expectation("; + switch (expect.shape.index()) { + case 0: + os << std::get(expect.shape); + if (expect.is_oval) { + os << " (oval)"; + } + break; + case 1: + os << std::get(expect.shape); + break; + case 2: + os << std::get(expect.shape); + break; + case 3: + os << "Unknown"; + } + os << ", " << expect.clip_op; + os << ", " << expect.is_aa; + os << ")"; + return os; +} + class ClipExpector : public virtual DlOpReceiver, virtual IgnoreAttributeDispatchHelper, virtual IgnoreTransformDispatchHelper, virtual IgnoreDrawDispatchHelper { public: - struct Expectation { - std::variant shape; - ClipOp clip_op; - bool is_aa; - - std::string shape_name() { - switch (shape.index()) { - case 0: - return "SkRect"; - case 1: - return "SkRRect"; - case 2: - return "SkPath"; - default: - return "Unknown"; - } - } - }; - // file and line supplied automatically from CLIP_EXPECTOR macro explicit ClipExpector(const std::string& file, int line) : file_(file), line_(line) {} ~ClipExpector() { // EXPECT_EQ(index_, clip_expectations_.size()) << label(); + while (index_ < clip_expectations_.size()) { + auto expect = clip_expectations_[index_]; + FML_LOG(ERROR) << "leftover clip shape[" << index_ << "] = " << expect; + index_++; + } } ClipExpector& addExpectation(const SkRect& rect, @@ -4369,6 +4397,19 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = rect, + .is_oval = false, + .clip_op = clip_op, + .is_aa = is_aa, + }); + return *this; + } + + ClipExpector& addOvalExpectation(const SkRect& rect, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) { + clip_expectations_.push_back({ + .shape = rect, + .is_oval = true, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4380,6 +4421,7 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = rrect, + .is_oval = false, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4391,6 +4433,7 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa = false) { clip_expectations_.push_back({ .shape = path, + .is_oval = false, .clip_op = clip_op, .is_aa = is_aa, }); @@ -4402,6 +4445,11 @@ class ClipExpector : public virtual DlOpReceiver, bool is_aa) override { check(rect, clip_op, is_aa); } + void clipOval(const SkRect& bounds, + DlCanvas::ClipOp clip_op, + bool is_aa) override { + check(bounds, clip_op, is_aa, true); + } void clipRRect(const SkRRect& rrect, DlCanvas::ClipOp clip_op, bool is_aa) override { @@ -4415,22 +4463,23 @@ class ClipExpector : public virtual DlOpReceiver, private: size_t index_ = 0; - std::vector clip_expectations_; + std::vector clip_expectations_; template - void check(T shape, ClipOp clip_op, bool is_aa) { + void check(T shape, ClipOp clip_op, bool is_aa, bool is_oval = false) { ASSERT_LT(index_, clip_expectations_.size()) << label() << std::endl - << "extra clip shape = " << shape; + << "extra clip shape = " << shape << (is_oval ? " (oval)" : ""); auto expected = clip_expectations_[index_]; - EXPECT_EQ(expected.clip_op, clip_op) << label(); - EXPECT_EQ(expected.is_aa, is_aa) << label(); if (!std::holds_alternative(expected.shape)) { EXPECT_TRUE(std::holds_alternative(expected.shape)) << label() << ", expected type: " << expected.shape_name(); } else { EXPECT_EQ(std::get(expected.shape), shape) << label(); } + EXPECT_EQ(expected.is_oval, is_oval) << label(); + EXPECT_EQ(expected.clip_op, clip_op) << label(); + EXPECT_EQ(expected.is_aa, is_aa) << label(); index_++; } @@ -4570,9 +4619,47 @@ TEST_F(DisplayListTest, ClipRectNestedNonCullingComplex) { cull_dl->Dispatch(expector); } +TEST_F(DisplayListTest, ClipOvalCulling) { + auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + // A 10x10 rectangle extends 5x5 from the center to each corner. To have + // an oval that encompasses that rectangle, the radius must be at least + // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 + // on each side to barely contain the corners of the square. + auto encompassing_oval = clip.makeOutset(2.072f, 2.072f); + + DisplayListBuilder cull_builder; + cull_builder.ClipRect(clip, ClipOp::kIntersect, false); + cull_builder.ClipOval(encompassing_oval, ClipOp::kIntersect, false); + auto cull_dl = cull_builder.Build(); + + CLIP_EXPECTOR(expector); + expector.addExpectation(clip, ClipOp::kIntersect, false); + cull_dl->Dispatch(expector); +} + +TEST_F(DisplayListTest, ClipOvalNonCulling) { + auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + // A 10x10 rectangle extends 5x5 from the center to each corner. To have + // an oval that encompasses that rectangle, the radius must be at least + // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 + // on each side to barely exclude the corners of the square. + auto non_encompassing_oval = clip.makeOutset(2.071f, 2.071f); + + DisplayListBuilder cull_builder; + cull_builder.ClipRect(clip, ClipOp::kIntersect, false); + cull_builder.ClipOval(non_encompassing_oval, ClipOp::kIntersect, false); + auto cull_dl = cull_builder.Build(); + + CLIP_EXPECTOR(expector); + expector.addExpectation(clip, ClipOp::kIntersect, false); + expector.addOvalExpectation(non_encompassing_oval, ClipOp::kIntersect, false); + cull_dl->Dispatch(expector); +} + TEST_F(DisplayListTest, ClipRRectCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 2.0f, 2.0f); + ASSERT_FALSE(rrect.isOval()); DisplayListBuilder cull_builder; cull_builder.ClipRect(clip, ClipOp::kIntersect, false); @@ -4586,7 +4673,8 @@ TEST_F(DisplayListTest, ClipRRectCulling) { TEST_F(DisplayListTest, ClipRRectNonCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 12.0f, 12.0f); + auto rrect = SkRRect::MakeRectXY(clip.makeOutset(1.0f, 1.0f), 4.0f, 4.0f); + ASSERT_FALSE(rrect.isOval()); DisplayListBuilder cull_builder; cull_builder.ClipRect(clip, ClipOp::kIntersect, false); @@ -4661,9 +4749,52 @@ TEST_F(DisplayListTest, ClipPathRectNonCulling) { cull_dl->Dispatch(expector); } +TEST_F(DisplayListTest, ClipPathOvalCulling) { + auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + // A 10x10 rectangle extends 5x5 from the center to each corner. To have + // an oval that encompasses that rectangle, the radius must be at least + // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 + // on each side to barely contain the corners of the square. + auto encompassing_oval = clip.makeOutset(2.072f, 2.072f); + SkPath path; + path.addOval(encompassing_oval); + + DisplayListBuilder cull_builder; + cull_builder.ClipRect(clip, ClipOp::kIntersect, false); + cull_builder.ClipPath(path, ClipOp::kIntersect, false); + auto cull_dl = cull_builder.Build(); + + CLIP_EXPECTOR(expector); + expector.addExpectation(clip, ClipOp::kIntersect, false); + cull_dl->Dispatch(expector); +} + +TEST_F(DisplayListTest, ClipPathOvalNonCulling) { + auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + // A 10x10 rectangle extends 5x5 from the center to each corner. To have + // an oval that encompasses that rectangle, the radius must be at least + // length(5, 5), or 7.071+ so we expand the radius 5 square clip by 2.072 + // on each side to barely exclude the corners of the square. + auto non_encompassing_oval = clip.makeOutset(2.071f, 2.071f); + SkPath path; + path.addOval(non_encompassing_oval); + + DisplayListBuilder cull_builder; + cull_builder.ClipRect(clip, ClipOp::kIntersect, false); + cull_builder.ClipPath(path, ClipOp::kIntersect, false); + auto cull_dl = cull_builder.Build(); + + CLIP_EXPECTOR(expector); + expector.addExpectation(clip, ClipOp::kIntersect, false); + // Builder will not cull this clip, but it will turn it into a ClipOval + expector.addOvalExpectation(non_encompassing_oval, ClipOp::kIntersect, false); + cull_dl->Dispatch(expector); +} + TEST_F(DisplayListTest, ClipPathRRectCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 2.0f, 2.0f); + ASSERT_FALSE(rrect.isOval()); SkPath path; path.addRRect(rrect); @@ -4679,7 +4810,8 @@ TEST_F(DisplayListTest, ClipPathRRectCulling) { TEST_F(DisplayListTest, ClipPathRRectNonCulling) { auto clip = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); - auto rrect = SkRRect::MakeRectXY(clip.makeOutset(2.0f, 2.0f), 12.0f, 12.0f); + auto rrect = SkRRect::MakeRectXY(clip.makeOutset(1.0f, 1.0f), 4.0f, 4.0f); + ASSERT_FALSE(rrect.isOval()); SkPath path; path.addRRect(rrect); @@ -4724,5 +4856,323 @@ TEST_F(DisplayListTest, RecordLargeVertices) { } } +TEST_F(DisplayListTest, DrawRectRRectPromoteToDrawRect) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + + DisplayListBuilder builder; + builder.DrawRRect(SkRRect::MakeRect(rect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawRect(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawOvalRRectPromoteToDrawOval) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + + DisplayListBuilder builder; + builder.DrawRRect(SkRRect::MakeOval(rect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawOval(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawRectPathPromoteToDrawRect) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::Rect(rect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawRect(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawOvalPathPromoteToDrawOval) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::Oval(rect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawOval(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawRRectPathPromoteToDrawRRect) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect rrect = SkRRect::MakeRectXY(rect, 2.0f, 2.0f); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::RRect(rrect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawRRect(rrect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawRectRRectPathPromoteToDrawRect) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect rrect = SkRRect::MakeRect(rect); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::RRect(rrect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawRect(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, DrawOvalRRectPathPromoteToDrawOval) { + SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect rrect = SkRRect::MakeOval(rect); + + DisplayListBuilder builder; + builder.DrawPath(SkPath::RRect(rrect), DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.DrawOval(rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipRectRRectPromoteToClipRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipRRect(SkRRect::MakeRect(clip_rect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipRect(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipOvalRRectPromoteToClipOval) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + + DisplayListBuilder builder; + builder.ClipRRect(SkRRect::MakeOval(clip_rect), ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipOval(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipRectPathPromoteToClipRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + SkPath clip_path = SkPath::Rect(clip_rect); + ASSERT_TRUE(clip_path.isRect(nullptr)); + ASSERT_FALSE(clip_path.isInverseFillType()); + + DisplayListBuilder builder; + builder.ClipPath(clip_path, ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipRect(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipOvalPathPromoteToClipOval) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + SkPath clip_path = SkPath::Oval(clip_rect); + ASSERT_TRUE(clip_path.isOval(nullptr)); + ASSERT_FALSE(clip_path.isInverseFillType()); + + DisplayListBuilder builder; + builder.ClipPath(clip_path, ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipOval(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipRRectPathPromoteToClipRRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect clip_rrect = SkRRect::MakeRectXY(clip_rect, 2.0f, 2.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + SkPath clip_path = SkPath::RRect(clip_rrect); + ASSERT_TRUE(clip_path.isRRect(nullptr)); + ASSERT_FALSE(clip_path.isInverseFillType()); + + DisplayListBuilder builder; + builder.ClipPath(clip_path, ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipRRect(clip_rrect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipRectInversePathNoPromoteToClipRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + SkPath clip_path = SkPath::Rect(clip_rect); + clip_path.toggleInverseFillType(); + ASSERT_TRUE(clip_path.isRect(nullptr)); + ASSERT_TRUE(clip_path.isInverseFillType()); + + DisplayListBuilder builder; + builder.ClipPath(clip_path, ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + // Non-promoting tests can't use DL comparisons to verify that the + // promotion isn't happening because the test and expectation builders + // would both apply or not apply the same optimization. For this case + // we use the CLIP_EXPECTOR instead to see exactly which type of + // clip operation was recorded. + CLIP_EXPECTOR(expector); + expector.addExpectation(clip_path, ClipOp::kIntersect, false); + dl->Dispatch(expector); +} + +TEST_F(DisplayListTest, ClipOvalInversePathNoPromoteToClipOval) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + SkPath clip_path = SkPath::Oval(clip_rect); + clip_path.toggleInverseFillType(); + ASSERT_TRUE(clip_path.isOval(nullptr)); + ASSERT_TRUE(clip_path.isInverseFillType()); + + DisplayListBuilder builder; + builder.ClipPath(clip_path, ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + // Non-promoting tests can't use DL comparisons to verify that the + // promotion isn't happening because the test and expectation builders + // would both apply or not apply the same optimization. For this case + // we use the CLIP_EXPECTOR instead to see exactly which type of + // clip operation was recorded. + CLIP_EXPECTOR(expector); + expector.addExpectation(clip_path, ClipOp::kIntersect, false); + dl->Dispatch(expector); +} + +TEST_F(DisplayListTest, ClipRRectInversePathNoPromoteToClipRRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect clip_rrect = SkRRect::MakeRectXY(clip_rect, 2.0f, 2.0f); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + SkPath clip_path = SkPath::RRect(clip_rrect); + clip_path.toggleInverseFillType(); + ASSERT_TRUE(clip_path.isRRect(nullptr)); + ASSERT_TRUE(clip_path.isInverseFillType()); + + DisplayListBuilder builder; + builder.ClipPath(clip_path, ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + // Non-promoting tests can't use DL comparisons to verify that the + // promotion isn't happening because the test and expectation builders + // would both apply or not apply the same optimization. For this case + // we use the CLIP_EXPECTOR instead to see exactly which type of + // clip operation was recorded. + CLIP_EXPECTOR(expector); + expector.addExpectation(clip_path, ClipOp::kIntersect, false); + dl->Dispatch(expector); +} + +TEST_F(DisplayListTest, ClipRectRRectPathPromoteToClipRect) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect clip_rrect = SkRRect::MakeRect(clip_rect); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + SkPath clip_path = SkPath::RRect(clip_rrect); + ASSERT_TRUE(clip_path.isRRect(nullptr)); + ASSERT_FALSE(clip_path.isInverseFillType()); + + DisplayListBuilder builder; + builder.ClipPath(clip_path, ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipRect(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + +TEST_F(DisplayListTest, ClipOvalRRectPathPromoteToClipOval) { + SkRect clip_rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f); + SkRRect clip_rrect = SkRRect::MakeOval(clip_rect); + SkRect draw_rect = clip_rect.makeOutset(2.0f, 2.0f); + SkPath clip_path = SkPath::RRect(clip_rrect); + ASSERT_TRUE(clip_path.isRRect(nullptr)); + ASSERT_FALSE(clip_path.isInverseFillType()); + + DisplayListBuilder builder; + builder.ClipPath(clip_path, ClipOp::kIntersect, false); + // Include a rendering op in case DlBuilder ever removes unneeded clips + builder.DrawRect(draw_rect, DlPaint()); + auto dl = builder.Build(); + + DisplayListBuilder expected; + expected.ClipOval(clip_rect, ClipOp::kIntersect, false); + expected.DrawRect(draw_rect, DlPaint()); + auto expect_dl = expected.Build(); + + DisplayListsEQ_Verbose(dl, expect_dl); +} + } // namespace testing } // namespace flutter diff --git a/display_list/dl_builder.cc b/display_list/dl_builder.cc index 98772c0d7a3ab..387455327e85f 100644 --- a/display_list/dl_builder.cc +++ b/display_list/dl_builder.cc @@ -963,14 +963,50 @@ void DisplayListBuilder::ClipRect(const SkRect& rect, break; } } +void DisplayListBuilder::ClipOval(const SkRect& bounds, + ClipOp clip_op, + bool is_aa) { + if (!bounds.isFinite()) { + return; + } + if (current_info().is_nop) { + return; + } + if (current_info().has_valid_clip && + clip_op == DlCanvas::ClipOp::kIntersect && + layer_local_state().oval_covers_cull(bounds)) { + return; + } + global_state().clipOval(bounds, clip_op, is_aa); + layer_local_state().clipOval(bounds, clip_op, is_aa); + if (global_state().is_cull_rect_empty() || + layer_local_state().is_cull_rect_empty()) { + current_info().is_nop = true; + return; + } + current_info().has_valid_clip = true; + checkForDeferredSave(); + switch (clip_op) { + case ClipOp::kIntersect: + Push(0, bounds, is_aa); + break; + case ClipOp::kDifference: + Push(0, bounds, is_aa); + break; + } +} void DisplayListBuilder::ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { + if (current_info().is_nop) { + return; + } if (rrect.isRect()) { clipRect(rrect.rect(), clip_op, is_aa); return; } - if (current_info().is_nop) { + if (rrect.isOval()) { + clipOval(rrect.rect(), clip_op, is_aa); return; } if (current_info().has_valid_clip && @@ -1008,12 +1044,11 @@ void DisplayListBuilder::ClipPath(const SkPath& path, this->clipRect(rect, clip_op, is_aa); return; } - SkRRect rrect; if (path.isOval(&rect)) { - rrect.setOval(rect); - this->clipRRect(rrect, clip_op, is_aa); + this->clipOval(rect, clip_op, is_aa); return; } + SkRRect rrect; if (path.isRRect(&rrect)) { this->clipRRect(rrect, clip_op, is_aa); return; @@ -1188,6 +1223,22 @@ void DisplayListBuilder::DrawDRRect(const SkRRect& outer, drawDRRect(outer, inner); } void DisplayListBuilder::drawPath(const SkPath& path) { + if (!path.isInverseFillType()) { + SkRect rect; + if (path.isRect(&rect)) { + drawRect(rect); + return; + } + if (path.isOval(&rect)) { + drawOval(rect); + return; + } + SkRRect rrect; + if (path.isRRect(&rrect)) { + drawRRect(rrect); + return; + } + } DisplayListAttributeFlags flags = kDrawPathFlags; OpResult result = PaintResult(current_, flags); if (result != OpResult::kNoEffect) { diff --git a/display_list/dl_builder.h b/display_list/dl_builder.h index b1a458f68eec9..dc75e2d37f6af 100644 --- a/display_list/dl_builder.h +++ b/display_list/dl_builder.h @@ -117,6 +117,10 @@ class DisplayListBuilder final : public virtual DlCanvas, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) override; // |DlCanvas| + void ClipOval(const SkRect& bounds, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) override; + // |DlCanvas| void ClipRRect(const SkRRect& rrect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) override; @@ -400,6 +404,10 @@ class DisplayListBuilder final : public virtual DlCanvas, ClipRect(rect, clip_op, is_aa); } // |DlOpReceiver| + void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override { + ClipOval(bounds, clip_op, is_aa); + } + // |DlOpReceiver| void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override { ClipRRect(rrect, clip_op, is_aa); } diff --git a/display_list/dl_canvas.h b/display_list/dl_canvas.h index ab505777aeae2..8fa4ad923f307 100644 --- a/display_list/dl_canvas.h +++ b/display_list/dl_canvas.h @@ -105,6 +105,9 @@ class DlCanvas { virtual void ClipRect(const SkRect& rect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) = 0; + virtual void ClipOval(const SkRect& bounds, + ClipOp clip_op = ClipOp::kIntersect, + bool is_aa = false) = 0; virtual void ClipRRect(const SkRRect& rrect, ClipOp clip_op = ClipOp::kIntersect, bool is_aa = false) = 0; diff --git a/display_list/dl_op_receiver.h b/display_list/dl_op_receiver.h index 8de5dae62c4d7..dc85e379e4176 100644 --- a/display_list/dl_op_receiver.h +++ b/display_list/dl_op_receiver.h @@ -328,6 +328,7 @@ class DlOpReceiver { virtual void transformReset() = 0; virtual void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) = 0; + virtual void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) = 0; virtual void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) = 0; virtual void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) = 0; diff --git a/display_list/dl_op_records.h b/display_list/dl_op_records.h index 3ad6eebe8fc54..aeb0379e2371f 100644 --- a/display_list/dl_op_records.h +++ b/display_list/dl_op_records.h @@ -566,11 +566,11 @@ struct TransformResetOp final : TransformClipOpBase { // the header, but the Windows compiler keeps wanting to expand that // packing into more bytes than needed (even when they are declared as // packed bit fields!) -#define DEFINE_CLIP_SHAPE_OP(shapetype, clipop) \ - struct Clip##clipop##shapetype##Op final : TransformClipOpBase { \ - static constexpr auto kType = DisplayListOpType::kClip##clipop##shapetype; \ +#define DEFINE_CLIP_SHAPE_OP(shapename, shapetype, clipop) \ + struct Clip##clipop##shapename##Op final : TransformClipOpBase { \ + static constexpr auto kType = DisplayListOpType::kClip##clipop##shapename; \ \ - Clip##clipop##shapetype##Op(Sk##shapetype shape, bool is_aa) \ + Clip##clipop##shapename##Op(Sk##shapetype shape, bool is_aa) \ : is_aa(is_aa), shape(shape) {} \ \ const bool is_aa; \ @@ -578,15 +578,17 @@ struct TransformResetOp final : TransformClipOpBase { \ void dispatch(DispatchContext& ctx) const { \ if (op_needed(ctx)) { \ - ctx.receiver.clip##shapetype(shape, DlCanvas::ClipOp::k##clipop, \ + ctx.receiver.clip##shapename(shape, DlCanvas::ClipOp::k##clipop, \ is_aa); \ } \ } \ }; -DEFINE_CLIP_SHAPE_OP(Rect, Intersect) -DEFINE_CLIP_SHAPE_OP(RRect, Intersect) -DEFINE_CLIP_SHAPE_OP(Rect, Difference) -DEFINE_CLIP_SHAPE_OP(RRect, Difference) +DEFINE_CLIP_SHAPE_OP(Rect, Rect, Intersect) +DEFINE_CLIP_SHAPE_OP(Oval, Rect, Intersect) +DEFINE_CLIP_SHAPE_OP(RRect, RRect, Intersect) +DEFINE_CLIP_SHAPE_OP(Rect, Rect, Difference) +DEFINE_CLIP_SHAPE_OP(Oval, Rect, Difference) +DEFINE_CLIP_SHAPE_OP(RRect, RRect, Difference) #undef DEFINE_CLIP_SHAPE_OP #define DEFINE_CLIP_PATH_OP(clipop) \ diff --git a/display_list/skia/dl_sk_canvas.cc b/display_list/skia/dl_sk_canvas.cc index a7334f303ec4b..235b654f41bca 100644 --- a/display_list/skia/dl_sk_canvas.cc +++ b/display_list/skia/dl_sk_canvas.cc @@ -153,6 +153,12 @@ void DlSkCanvasAdapter::ClipRect(const SkRect& rect, delegate_->clipRect(rect, ToSk(clip_op), is_aa); } +void DlSkCanvasAdapter::ClipOval(const SkRect& bounds, + ClipOp clip_op, + bool is_aa) { + delegate_->clipRRect(SkRRect::MakeOval(bounds), ToSk(clip_op), is_aa); +} + void DlSkCanvasAdapter::ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/display_list/skia/dl_sk_canvas.h b/display_list/skia/dl_sk_canvas.h index c61f3f465455e..5ceebe561ef6b 100644 --- a/display_list/skia/dl_sk_canvas.h +++ b/display_list/skia/dl_sk_canvas.h @@ -72,6 +72,7 @@ class DlSkCanvasAdapter final : public virtual DlCanvas { SkMatrix GetTransform() const override; void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void ClipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/display_list/skia/dl_sk_dispatcher.cc b/display_list/skia/dl_sk_dispatcher.cc index 84c7115fb5fa4..819860d3fb184 100644 --- a/display_list/skia/dl_sk_dispatcher.cc +++ b/display_list/skia/dl_sk_dispatcher.cc @@ -122,6 +122,11 @@ void DlSkCanvasDispatcher::clipRect(const SkRect& rect, bool is_aa) { canvas_->clipRect(rect, ToSk(clip_op), is_aa); } +void DlSkCanvasDispatcher::clipOval(const SkRect& bounds, + ClipOp clip_op, + bool is_aa) { + canvas_->clipRRect(SkRRect::MakeOval(bounds), ToSk(clip_op), is_aa); +} void DlSkCanvasDispatcher::clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/display_list/skia/dl_sk_dispatcher.h b/display_list/skia/dl_sk_dispatcher.h index ef15f8152e736..384f722633677 100644 --- a/display_list/skia/dl_sk_dispatcher.h +++ b/display_list/skia/dl_sk_dispatcher.h @@ -51,6 +51,7 @@ class DlSkCanvasDispatcher : public virtual DlOpReceiver, void transformReset() override; void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/display_list/testing/dl_rendering_unittests.cc b/display_list/testing/dl_rendering_unittests.cc index 89102029e175b..1368f3e921fbe 100644 --- a/display_list/testing/dl_rendering_unittests.cc +++ b/display_list/testing/dl_rendering_unittests.cc @@ -2073,6 +2073,39 @@ class CanvasCompareTester { ctx.canvas->ClipRect(r_clip, ClipOp::kDifference, false); }) .with_diff_clip()); + // Skia lacks clipOval and requires us to make an oval SkRRect + SkRRect rr_oval_clip = SkRRect::MakeOval(r_clip); + RenderWith(testP, env, intersect_tolerance, + CaseParameters( + "Hard ClipOval", + [=](const SkSetupContext& ctx) { + ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kIntersect, + false); + }, + [=](const DlSetupContext& ctx) { + ctx.canvas->ClipOval(r_clip, ClipOp::kIntersect, false); + })); + RenderWith(testP, env, intersect_tolerance, + CaseParameters( + "AntiAlias ClipOval", + [=](const SkSetupContext& ctx) { + ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kIntersect, + true); + }, + [=](const DlSetupContext& ctx) { + ctx.canvas->ClipOval(r_clip, ClipOp::kIntersect, true); + })); + RenderWith(testP, env, diff_tolerance, + CaseParameters( + "Hard ClipOval Diff", + [=](const SkSetupContext& ctx) { + ctx.canvas->clipRRect(rr_oval_clip, SkClipOp::kDifference, + false); + }, + [=](const DlSetupContext& ctx) { + ctx.canvas->ClipOval(r_clip, ClipOp::kDifference, false); + }) + .with_diff_clip()); // This test RR clip used to use very small radii, but due to // optimizations in the HW rrect rasterization, this caused small // bulges in the corners of the RRect which were interpreted as @@ -2850,12 +2883,14 @@ TEST_F(DisplayListRendering, DrawDiagonalLines) { SkPoint p2 = SkPoint::Make(kRenderRight, kRenderBottom); SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderBottom); SkPoint p4 = SkPoint::Make(kRenderRight, kRenderTop); + // Adding some edge to edge diagonals that run through the points about + // 16 units in from the center of that edge. // Adding some edge center to edge center diagonals to better fill // out the RRect Clip so bounds checking sees less empty bounds space. - SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop); - SkPoint p6 = SkPoint::Make(kRenderRight, kRenderCenterY); - SkPoint p7 = SkPoint::Make(kRenderLeft, kRenderCenterY); - SkPoint p8 = SkPoint::Make(kRenderCenterX, kRenderBottom); + SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop + 15); + SkPoint p6 = SkPoint::Make(kRenderRight - 15, kRenderCenterY); + SkPoint p7 = SkPoint::Make(kRenderCenterX, kRenderBottom - 15); + SkPoint p8 = SkPoint::Make(kRenderLeft + 15, kRenderCenterY); CanvasCompareTester::RenderAll( // TestParameters( @@ -2880,9 +2915,13 @@ TEST_F(DisplayListRendering, DrawDiagonalLines) { .set_draw_line()); } -TEST_F(DisplayListRendering, DrawHorizontalLine) { - SkPoint p1 = SkPoint::Make(kRenderLeft, kRenderCenterY); - SkPoint p2 = SkPoint::Make(kRenderRight, kRenderCenterY); +TEST_F(DisplayListRendering, DrawHorizontalLines) { + SkPoint p1 = SkPoint::Make(kRenderLeft, kRenderTop + 16); + SkPoint p2 = SkPoint::Make(kRenderRight, kRenderTop + 16); + SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderCenterY); + SkPoint p4 = SkPoint::Make(kRenderRight, kRenderCenterY); + SkPoint p5 = SkPoint::Make(kRenderLeft, kRenderBottom - 16); + SkPoint p6 = SkPoint::Make(kRenderRight, kRenderBottom - 16); CanvasCompareTester::RenderAll( // TestParameters( @@ -2893,18 +2932,26 @@ TEST_F(DisplayListRendering, DrawHorizontalLine) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); ctx.canvas->drawLine(p1, p2, p); + ctx.canvas->drawLine(p3, p4, p); + ctx.canvas->drawLine(p5, p6, p); }, [=](const DlRenderContext& ctx) { // ctx.canvas->DrawLine(p1, p2, ctx.paint); + ctx.canvas->DrawLine(p3, p4, ctx.paint); + ctx.canvas->DrawLine(p5, p6, ctx.paint); }, kDrawHVLineFlags) .set_draw_line() .set_horizontal_line()); } -TEST_F(DisplayListRendering, DrawVerticalLine) { - SkPoint p1 = SkPoint::Make(kRenderCenterX, kRenderTop); - SkPoint p2 = SkPoint::Make(kRenderCenterY, kRenderBottom); +TEST_F(DisplayListRendering, DrawVerticalLines) { + SkPoint p1 = SkPoint::Make(kRenderLeft + 16, kRenderTop); + SkPoint p2 = SkPoint::Make(kRenderLeft + 16, kRenderBottom); + SkPoint p3 = SkPoint::Make(kRenderCenterX, kRenderTop); + SkPoint p4 = SkPoint::Make(kRenderCenterX, kRenderBottom); + SkPoint p5 = SkPoint::Make(kRenderRight - 16, kRenderTop); + SkPoint p6 = SkPoint::Make(kRenderRight - 16, kRenderBottom); CanvasCompareTester::RenderAll( // TestParameters( @@ -2915,9 +2962,13 @@ TEST_F(DisplayListRendering, DrawVerticalLine) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); ctx.canvas->drawLine(p1, p2, p); + ctx.canvas->drawLine(p3, p4, p); + ctx.canvas->drawLine(p5, p6, p); }, [=](const DlRenderContext& ctx) { // ctx.canvas->DrawLine(p1, p2, ctx.paint); + ctx.canvas->DrawLine(p3, p4, ctx.paint); + ctx.canvas->DrawLine(p5, p6, ctx.paint); }, kDrawHVLineFlags) .set_draw_line() @@ -2929,12 +2980,14 @@ TEST_F(DisplayListRendering, DrawDiagonalDashedLines) { SkPoint p2 = SkPoint::Make(kRenderRight, kRenderBottom); SkPoint p3 = SkPoint::Make(kRenderLeft, kRenderBottom); SkPoint p4 = SkPoint::Make(kRenderRight, kRenderTop); + // Adding some edge to edge diagonals that run through the points about + // 16 units in from the center of that edge. // Adding some edge center to edge center diagonals to better fill // out the RRect Clip so bounds checking sees less empty bounds space. - SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop); - SkPoint p6 = SkPoint::Make(kRenderRight, kRenderCenterY); - SkPoint p7 = SkPoint::Make(kRenderLeft, kRenderCenterY); - SkPoint p8 = SkPoint::Make(kRenderCenterX, kRenderBottom); + SkPoint p5 = SkPoint::Make(kRenderCenterX, kRenderTop + 15); + SkPoint p6 = SkPoint::Make(kRenderRight - 15, kRenderCenterY); + SkPoint p7 = SkPoint::Make(kRenderCenterX, kRenderBottom - 15); + SkPoint p8 = SkPoint::Make(kRenderLeft + 15, kRenderCenterY); // Full diagonals are 100x100 which are 140 in length // Dashing them with 25 on, 5 off means that the last @@ -2955,7 +3008,7 @@ TEST_F(DisplayListRendering, DrawDiagonalDashedLines) { SkPaint p = ctx.paint; p.setStyle(SkPaint::kStroke_Style); SkScalar intervals[2] = {25.0f, 5.0f}; - p.setPathEffect(SkDashPathEffect::Make(intervals, 2.0f, 0.0f)); + p.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0.0f)); ctx.canvas->drawLine(p1, p2, p); ctx.canvas->drawLine(p3, p4, p); ctx.canvas->drawLine(p5, p6, p); @@ -3125,7 +3178,7 @@ TEST_F(DisplayListRendering, DrawPointsAsPoints) { const SkScalar x3 = kRenderCenterX + 0.1; const SkScalar x4 = (kRenderRight + kRenderCenterX) * 0.5; const SkScalar x5 = kRenderRight - 16; - const SkScalar x6 = kRenderRight; + const SkScalar x6 = kRenderRight - 1; const SkScalar y0 = kRenderTop; const SkScalar y1 = kRenderTop + 16; @@ -3133,7 +3186,7 @@ TEST_F(DisplayListRendering, DrawPointsAsPoints) { const SkScalar y3 = kRenderCenterY + 0.1; const SkScalar y4 = (kRenderBottom + kRenderCenterY) * 0.5; const SkScalar y5 = kRenderBottom - 16; - const SkScalar y6 = kRenderBottom; + const SkScalar y6 = kRenderBottom - 1; // clang-format off const SkPoint points[] = { @@ -3177,7 +3230,7 @@ TEST_F(DisplayListRendering, DrawPointsAsLines) { const SkScalar y0 = kRenderTop; const SkScalar y1 = kRenderTop + 16; const SkScalar y2 = kRenderBottom - 16; - const SkScalar y3 = kRenderBottom; + const SkScalar y3 = kRenderBottom - 1; // clang-format off const SkPoint points[] = { @@ -3226,10 +3279,12 @@ TEST_F(DisplayListRendering, DrawPointsAsPolygon) { SkPoint::Make(kRenderRight, kRenderBottom), SkPoint::Make(kRenderLeft, kRenderBottom), SkPoint::Make(kRenderLeft, kRenderTop), - SkPoint::Make(kRenderCenterX, kRenderTop), - SkPoint::Make(kRenderRight, kRenderCenterY), - SkPoint::Make(kRenderCenterX, kRenderBottom), - SkPoint::Make(kRenderLeft, kRenderCenterY), + + SkPoint::Make(kRenderCenterX, kRenderTop + 15), + SkPoint::Make(kRenderRight - 15, kRenderCenterY), + SkPoint::Make(kRenderCenterX, kRenderBottom - 15), + SkPoint::Make(kRenderLeft + 15, kRenderCenterY), + SkPoint::Make(kRenderCenterX, kRenderTop + 15), }; const int count1 = sizeof(points1) / sizeof(points1[0]); @@ -3730,7 +3785,7 @@ TEST_F(DisplayListRendering, DrawShadow) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 5; + const SkScalar elevation = 7; CanvasCompareTester::RenderAll( // TestParameters( @@ -3756,7 +3811,7 @@ TEST_F(DisplayListRendering, DrawShadowTransparentOccluder) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 5; + const SkScalar elevation = 7; CanvasCompareTester::RenderAll( // TestParameters( @@ -3782,7 +3837,7 @@ TEST_F(DisplayListRendering, DrawShadowDpr) { }, kRenderCornerRadius, kRenderCornerRadius); const DlColor color = DlColor::kDarkGrey(); - const SkScalar elevation = 5; + const SkScalar elevation = 7; CanvasCompareTester::RenderAll( // TestParameters( diff --git a/display_list/testing/dl_test_snippets.cc b/display_list/testing/dl_test_snippets.cc index e5ad4b2f365dc..16c0edb5d4468 100644 --- a/display_list/testing/dl_test_snippets.cc +++ b/display_list/testing/dl_test_snippets.cc @@ -424,6 +424,30 @@ std::vector CreateAllClipOps() { r.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, false); }}, }}, + {"ClipOval", + { + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds, DlCanvas::ClipOp::kIntersect, true); + }}, + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds.makeOffset(1, 1), + DlCanvas::ClipOp::kIntersect, true); + }}, + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds, DlCanvas::ClipOp::kIntersect, false); + }}, + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds, DlCanvas::ClipOp::kDifference, true); + }}, + {1, 24, 0, + [](DlOpReceiver& r) { + r.clipOval(kTestBounds, DlCanvas::ClipOp::kDifference, false); + }}, + }}, {"ClipRRect", { {1, 64, 0, @@ -479,11 +503,16 @@ std::vector CreateAllClipOps() { [](DlOpReceiver& r) { r.clipPath(kTestPathRect, DlCanvas::ClipOp::kIntersect, true); }}, - // clipPath(oval) becomes clipRRect - {1, 64, 0, + // clipPath(oval) becomes clipOval + {1, 24, 0, [](DlOpReceiver& r) { r.clipPath(kTestPathOval, DlCanvas::ClipOp::kIntersect, true); }}, + // clipPath(rrect) becomes clipRRect + {1, 64, 0, + [](DlOpReceiver& r) { + r.clipPath(kTestPathRRect, DlCanvas::ClipOp::kIntersect, true); + }}, }}, }; } @@ -637,8 +666,11 @@ std::vector CreateAllRenderingOps() { {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath1); }}, {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath2); }}, {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath3); }}, - {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }}, - {1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }}, + // oval and rect paths are redirected to drawRect and drawOval + {1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }}, + {1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }}, + // rrect path is redirected to drawRRect + {1, 56, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRRect); }}, }}, {"DrawArc", { diff --git a/display_list/testing/dl_test_snippets.h b/display_list/testing/dl_test_snippets.h index 16d740c2fb6a0..733ce67364034 100644 --- a/display_list/testing/dl_test_snippets.h +++ b/display_list/testing/dl_test_snippets.h @@ -183,6 +183,7 @@ static const SkRRect kTestInnerRRect = SkRRect::MakeRectXY(kTestBounds.makeInset(5, 5), 2, 2); static const SkPath kTestPathRect = SkPath::Rect(kTestBounds); static const SkPath kTestPathOval = SkPath::Oval(kTestBounds); +static const SkPath kTestPathRRect = SkPath::RRect(kTestRRect); static const SkPath kTestPath1 = SkPath::Polygon({{0, 0}, {10, 10}, {10, 0}, {0, 10}}, true); static const SkPath kTestPath2 = diff --git a/display_list/utils/dl_matrix_clip_tracker.cc b/display_list/utils/dl_matrix_clip_tracker.cc index 748cf07a8385a..86f3cff46a6d9 100644 --- a/display_list/utils/dl_matrix_clip_tracker.cc +++ b/display_list/utils/dl_matrix_clip_tracker.cc @@ -74,6 +74,24 @@ void DisplayListMatrixClipState::clipRect(const DlRect& rect, } } +void DisplayListMatrixClipState::clipOval(const DlRect& bounds, + ClipOp op, + bool is_aa) { + if (!bounds.IsFinite()) { + return; + } + switch (op) { + case DlCanvas::ClipOp::kIntersect: + adjustCullRect(bounds, op, is_aa); + break; + case DlCanvas::ClipOp::kDifference: + if (oval_covers_cull(bounds)) { + cull_rect_ = DlRect(); + } + break; + } +} + void DisplayListMatrixClipState::clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) { diff --git a/display_list/utils/dl_matrix_clip_tracker.h b/display_list/utils/dl_matrix_clip_tracker.h index 59c9880bd3bd7..4a6198d75a3e1 100644 --- a/display_list/utils/dl_matrix_clip_tracker.h +++ b/display_list/utils/dl_matrix_clip_tracker.h @@ -149,6 +149,10 @@ class DisplayListMatrixClipState { void clipRect(const SkRect& rect, ClipOp op, bool is_aa) { clipRect(ToDlRect(rect), op, is_aa); } + void clipOval(const DlRect& bounds, ClipOp op, bool is_aa); + void clipOval(const SkRect& bounds, ClipOp op, bool is_aa) { + clipRect(ToDlRect(bounds), op, is_aa); + } void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa); void clipPath(const SkPath& path, ClipOp op, bool is_aa); diff --git a/display_list/utils/dl_receiver_utils.h b/display_list/utils/dl_receiver_utils.h index d50cb00cba057..bb6ce6539f653 100644 --- a/display_list/utils/dl_receiver_utils.h +++ b/display_list/utils/dl_receiver_utils.h @@ -44,6 +44,9 @@ class IgnoreClipDispatchHelper : public virtual DlOpReceiver { void clipRect(const SkRect& rect, DlCanvas::ClipOp clip_op, bool is_aa) override {} + void clipOval(const SkRect& bounds, + DlCanvas::ClipOp clip_op, + bool is_aa) override {} void clipRRect(const SkRRect& rrect, DlCanvas::ClipOp clip_op, bool is_aa) override {} diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index f1b6552b34c97..2a2bfb2f78609 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -723,6 +723,14 @@ void DlDispatcherBase::clipRect(const SkRect& rect, ToClipOperation(clip_op)); } +// |flutter::DlOpReceiver| +void DlDispatcherBase::clipOval(const SkRect& bounds, + ClipOp clip_op, + bool is_aa) { + GetCanvas().ClipOval(skia_conversions::ToRect(bounds), + ToClipOperation(clip_op)); +} + // |flutter::DlOpReceiver| void DlDispatcherBase::clipRRect(const SkRRect& rrect, ClipOp sk_op, diff --git a/impeller/display_list/dl_dispatcher.h b/impeller/display_list/dl_dispatcher.h index 7349ca7e4fd84..294616b748776 100644 --- a/impeller/display_list/dl_dispatcher.h +++ b/impeller/display_list/dl_dispatcher.h @@ -123,6 +123,9 @@ class DlDispatcherBase : public flutter::DlOpReceiver { // |flutter::DlOpReceiver| void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + // |flutter::DlOpReceiver| + void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; + // |flutter::DlOpReceiver| void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; diff --git a/testing/display_list_testing.cc b/testing/display_list_testing.cc index 8cf84bc270242..ce831ca247813 100644 --- a/testing/display_list_testing.cc +++ b/testing/display_list_testing.cc @@ -742,6 +742,14 @@ void DisplayListStreamDispatcher::clipRect(const SkRect& rect, ClipOp clip_op, << "isaa: " << is_aa << ");" << std::endl; } +void DisplayListStreamDispatcher::clipOval(const SkRect& bounds, ClipOp clip_op, + bool is_aa) { + startl() << "clipOval(" + << bounds << ", " + << clip_op << ", " + << "isaa: " << is_aa + << ");" << std::endl; +} void DisplayListStreamDispatcher::clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { diff --git a/testing/display_list_testing.h b/testing/display_list_testing.h index b710e1e22af45..2ccb011dedcf0 100644 --- a/testing/display_list_testing.h +++ b/testing/display_list_testing.h @@ -118,6 +118,7 @@ class DisplayListStreamDispatcher final : public DlOpReceiver { void transformReset() override; void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void clipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc index 695678e23a0ee..03627f722fbaa 100644 --- a/testing/mock_canvas.cc +++ b/testing/mock_canvas.cc @@ -214,6 +214,13 @@ void MockCanvas::ClipRect(const SkRect& rect, ClipOp op, bool is_aa) { state_stack_.back().clipRect(rect, op, is_aa); } +void MockCanvas::ClipOval(const SkRect& bounds, ClipOp op, bool is_aa) { + ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle; + draw_calls_.emplace_back( + DrawCall{current_layer_, ClipOvalData{bounds, op, style}}); + state_stack_.back().clipOval(bounds, op, is_aa); +} + void MockCanvas::ClipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) { ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle; draw_calls_.emplace_back( @@ -520,6 +527,16 @@ std::ostream& operator<<(std::ostream& os, return os << data.rect << " " << data.clip_op << " " << data.style; } +bool operator==(const MockCanvas::ClipOvalData& a, + const MockCanvas::ClipOvalData& b) { + return a.bounds == b.bounds && a.clip_op == b.clip_op && a.style == b.style; +} + +std::ostream& operator<<(std::ostream& os, + const MockCanvas::ClipOvalData& data) { + return os << data.bounds << " " << data.clip_op << " " << data.style; +} + bool operator==(const MockCanvas::ClipRRectData& a, const MockCanvas::ClipRRectData& b) { return a.rrect == b.rrect && a.clip_op == b.clip_op && a.style == b.style; diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h index f15e0ec54adf2..7384d5ecf578a 100644 --- a/testing/mock_canvas.h +++ b/testing/mock_canvas.h @@ -114,6 +114,12 @@ class MockCanvas final : public DlCanvas { ClipEdgeStyle style; }; + struct ClipOvalData { + SkRect bounds; + ClipOp clip_op; + ClipEdgeStyle style; + }; + struct ClipRRectData { SkRRect rrect; ClipOp clip_op; @@ -145,6 +151,7 @@ class MockCanvas final : public DlCanvas { DrawDisplayListData, DrawShadowData, ClipRectData, + ClipOvalData, ClipRRectData, ClipPathData, DrawPaintData>; @@ -206,6 +213,7 @@ class MockCanvas final : public DlCanvas { SkMatrix GetTransform() const override; void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override; + void ClipOval(const SkRect& bounds, ClipOp clip_op, bool is_aa) override; void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override; void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override; From ad1343cfb99e9fd1b9bc4d924b6af2d11601a5ed Mon Sep 17 00:00:00 2001 From: Yegor Date: Fri, 28 Jun 2024 14:35:10 -0700 Subject: [PATCH 86/88] [web] switch from .didGain/LoseAccessibilityFocus to .focus (#53360) This is a repeat of https://github.com/flutter/engine/pull/53134, which was merged prematurely. > [!WARNING] > Only land this after: > * https://github.com/flutter/flutter/pull/149840 lands in the framework. > * You have personally manually tested the change together with the latest framework on all browsers. ## Original PR description Stop using `SemanticsAction.didGain/LoseAccessibilityFocus` on the web, start using `SemanticsAction.focus`. This is because on the web, a11y focus is not observable, only input focus is. Sending `SemanticsAction.focus` will guarantee that the framework move focus to the respective widget. There currently is no "unfocus" signal, because it seems to be already covered: either another widget gains focus, or an HTML DOM element outside the Flutter view does, both of which have their respective signals already. More details in the discussion in the issue https://github.com/flutter/flutter/issues/83809. Fixes https://github.com/flutter/flutter/issues/83809 Fixes https://github.com/flutter/flutter/issues/148285 Fixes https://github.com/flutter/flutter/issues/143337 --- lib/ui/semantics.dart | 3 + lib/web_ui/lib/src/engine/dom.dart | 24 + .../lib/src/engine/semantics/focusable.dart | 17 +- .../lib/src/engine/semantics/semantics.dart | 2 - .../lib/src/engine/semantics/text_field.dart | 258 ++----- .../src/engine/text_editing/text_editing.dart | 24 +- .../test/engine/semantics/semantics_test.dart | 94 +-- .../engine/semantics/semantics_tester.dart | 4 + .../engine/semantics/text_field_test.dart | 729 ++++-------------- 9 files changed, 257 insertions(+), 898 deletions(-) diff --git a/lib/ui/semantics.dart b/lib/ui/semantics.dart index 57bc1fa30726d..481c9c3cbc525 100644 --- a/lib/ui/semantics.dart +++ b/lib/ui/semantics.dart @@ -220,6 +220,9 @@ class SemanticsAction { /// must immediately become editable, opening a virtual keyboard, if needed. /// Buttons must respond to tap/click events from the keyboard. /// + /// Widget reaction to this action must be idempotent. It is possible to + /// receive this action more than once, or when the widget is already focused. + /// /// Focus behavior is specific to the platform and to the assistive technology /// used. Typically on desktop operating systems, such as Windows, macOS, and /// Linux, moving accessibility focus will also move the input focus. On diff --git a/lib/web_ui/lib/src/engine/dom.dart b/lib/web_ui/lib/src/engine/dom.dart index 622cf3f2a2dd1..42f6cfa1a2265 100644 --- a/lib/web_ui/lib/src/engine/dom.dart +++ b/lib/web_ui/lib/src/engine/dom.dart @@ -2748,6 +2748,30 @@ DomCompositionEvent createDomCompositionEvent(String type, } } +/// This is a pseudo-type for DOM elements that have the boolean `disabled` +/// property. +/// +/// This type cannot be part of the actual type hierarchy because each DOM type +/// defines its `disabled` property ad hoc, without inheriting it from a common +/// type, e.g. [DomHTMLInputElement] and [DomHTMLTextAreaElement]. +/// +/// To use, simply cast any element known to have the `disabled` property to +/// this type using `as DomElementWithDisabledProperty`, then read and write +/// this property as normal. +@JS() +@staticInterop +class DomElementWithDisabledProperty extends DomHTMLElement {} + +extension DomElementWithDisabledPropertyExtension on DomElementWithDisabledProperty { + @JS('disabled') + external JSBoolean? get _disabled; + bool? get disabled => _disabled?.toDart; + + @JS('disabled') + external set _disabled(JSBoolean? value); + set disabled(bool? value) => _disabled = value?.toJS; +} + @JS() @staticInterop class DomHTMLInputElement extends DomHTMLElement {} diff --git a/lib/web_ui/lib/src/engine/semantics/focusable.dart b/lib/web_ui/lib/src/engine/semantics/focusable.dart index 35fff64a50158..331e1cd50c061 100644 --- a/lib/web_ui/lib/src/engine/semantics/focusable.dart +++ b/lib/web_ui/lib/src/engine/semantics/focusable.dart @@ -81,9 +81,6 @@ typedef _FocusTarget = ({ /// The listener for the "focus" DOM event. DomEventListener domFocusListener, - - /// The listener for the "blur" DOM event. - DomEventListener domBlurListener, }); /// Implements accessibility focus management for arbitrary elements. @@ -135,7 +132,6 @@ class AccessibilityFocusManager { semanticsNodeId: semanticsNodeId, element: previousTarget.element, domFocusListener: previousTarget.domFocusListener, - domBlurListener: previousTarget.domBlurListener, ); return; } @@ -148,14 +144,12 @@ class AccessibilityFocusManager { final _FocusTarget newTarget = ( semanticsNodeId: semanticsNodeId, element: element, - domFocusListener: createDomEventListener((_) => _setFocusFromDom(true)), - domBlurListener: createDomEventListener((_) => _setFocusFromDom(false)), + domFocusListener: createDomEventListener((_) => _didReceiveDomFocus()), ); _target = newTarget; element.tabIndex = 0; element.addEventListener('focus', newTarget.domFocusListener); - element.addEventListener('blur', newTarget.domBlurListener); } /// Stops managing the focus of the current element, if any. @@ -170,10 +164,9 @@ class AccessibilityFocusManager { } target.element.removeEventListener('focus', target.domFocusListener); - target.element.removeEventListener('blur', target.domBlurListener); } - void _setFocusFromDom(bool acquireFocus) { + void _didReceiveDomFocus() { final _FocusTarget? target = _target; if (target == null) { @@ -184,9 +177,7 @@ class AccessibilityFocusManager { EnginePlatformDispatcher.instance.invokeOnSemanticsAction( target.semanticsNodeId, - acquireFocus - ? ui.SemanticsAction.didGainAccessibilityFocus - : ui.SemanticsAction.didLoseAccessibilityFocus, + ui.SemanticsAction.focus, null, ); } @@ -229,7 +220,7 @@ class AccessibilityFocusManager { // a dialog, and nothing else in the dialog is focused. The Flutter // framework expects that the screen reader will focus on the first (in // traversal order) focusable element inside the dialog and send a - // didGainAccessibilityFocus action. Screen readers on the web do not do + // SemanticsAction.focus action. Screen readers on the web do not do // that, and so the web engine has to implement this behavior directly. So // the dialog will look for a focusable element and request focus on it, // but now there may be a race between this method unsetting the focus and diff --git a/lib/web_ui/lib/src/engine/semantics/semantics.dart b/lib/web_ui/lib/src/engine/semantics/semantics.dart index c48851d9836a2..0918ef49c3ff7 100644 --- a/lib/web_ui/lib/src/engine/semantics/semantics.dart +++ b/lib/web_ui/lib/src/engine/semantics/semantics.dart @@ -2218,8 +2218,6 @@ class EngineSemantics { 'mousemove', 'mouseleave', 'mouseup', - 'keyup', - 'keydown', ]; if (pointerEventTypes.contains(event.type)) { diff --git a/lib/web_ui/lib/src/engine/semantics/text_field.dart b/lib/web_ui/lib/src/engine/semantics/text_field.dart index bb79ea1df52d9..3618306d37829 100644 --- a/lib/web_ui/lib/src/engine/semantics/text_field.dart +++ b/lib/web_ui/lib/src/engine/semantics/text_field.dart @@ -2,11 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:async'; import 'package:ui/ui.dart' as ui; -import 'package:ui/ui_web/src/ui_web.dart' as ui_web; -import '../browser_detection.dart' show isIosSafari; import '../dom.dart'; import '../platform_dispatcher.dart'; import '../text_editing/text_editing.dart'; @@ -123,7 +120,10 @@ class SemanticsTextEditingStrategy extends DefaultTextEditingStrategy { // Android). // Otherwise, the keyboard stays on screen even when the user navigates to // a different screen (e.g. by hitting the "back" button). - domElement?.blur(); + // Keep this consistent with how DefaultTextEditingStrategy does it. As of + // right now, the only difference is that semantic text fields do not + // participate in form autofill. + DefaultTextEditingStrategy.scheduleFocusFlutterView(activeDomElement, activeDomElementView); domElement = null; activeTextField = null; _queuedStyle = null; @@ -162,7 +162,7 @@ class SemanticsTextEditingStrategy extends DefaultTextEditingStrategy { if (hasAutofillGroup) { placeForm(); } - activeDomElement.focus(); + activeDomElement.focus(preventScroll: true); } @override @@ -207,69 +207,40 @@ class SemanticsTextEditingStrategy extends DefaultTextEditingStrategy { /// [EngineSemanticsOwner.gestureMode]. However, in Chrome on Android it ignores /// browser gestures when in pointer mode. In Safari on iOS pointer events are /// used to detect text box invocation. This is because Safari issues touch -/// events even when Voiceover is enabled. +/// events even when VoiceOver is enabled. class TextField extends PrimaryRoleManager { TextField(SemanticsObject semanticsObject) : super.blank(PrimaryRole.textField, semanticsObject) { - _setupDomElement(); + _initializeEditableElement(); } - /// The element used for editing, e.g. ``, `