diff --git a/.cirrus.yml b/.cirrus.yml index 9dde213d2698d..4ffcb70c8b256 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,20 +1,28 @@ gcp_credentials: ENCRYPTED[987a78af29b91ce8489594c9ab3fec21845bbe5ba68294b8f6def3cf0d380830f06687a89ea69c87344c5ade369700fe] -gke_container: - image: gcr.io/flutter-cirrus/build-engine-image:latest - cluster_name: build-32-cluster - zone: us-central1-a - namespace: default - cpu: 30 # can't use all 30-cores; system pods needs cores too - memory: 100Gb # similarly, can't use all 100Gb memory - task: + gke_container: + image: gcr.io/flutter-cirrus/build-engine-image:latest + cluster_name: build-32-cluster + zone: us-central1-a + namespace: default + cpu: 30 # can't use all 30-cores; system pods needs cores too + memory: 100Gb # similarly, can't use all 100Gb memory env: CIRRUS_WORKING_DIR: "/tmp/github_repo" - - replace_engine_script: | + ENGINE_PATH: "/tmp/clean_engine" + DEPOT_TOOLS: "/tmp/depot_tools" + FLUTTER_ENGINE: "/tmp/clean_engine/src" + FRAMEWORK_PATH: "/tmp/master_framework" + PATH: "$FLUTTER_ENGINE/third_party/dart/tools/sdks/dart-sdk/bin:$DEPOT_TOOLS:$PATH" + depot_tools_script: + git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git $DEPOT_TOOLS + gclient_sync_script: | + mkdir -p $ENGINE_PATH/src + echo 'solutions = [{"managed": False,"name": "src/flutter","url": "git@github.com:flutter/engine.git","deps_file": "DEPS", "custom_vars": {"download_android_deps" : False, "download_windows_deps" : False,},},]' > $ENGINE_PATH/.gclient cd $ENGINE_PATH/src - rm -r flutter + rm -rf flutter + rm -rf out mv $CIRRUS_WORKING_DIR flutter gclient sync @@ -24,27 +32,79 @@ task: cd $ENGINE_PATH/src ./flutter/tools/gn --unoptimized ninja -C out/host_debug_unopt - test_host_script: cd $ENGINE_PATH/src && ./flutter/testing/run_tests.sh + test_host_script: cd $ENGINE_PATH/src && ./flutter/testing/run_tests.sh host_debug_unopt + fetch_framework_script: | + mkdir -p $FRAMEWORK_PATH + cd $FRAMEWORK_PATH + git clone https://github.com/flutter/flutter.git + framework_test_script: | + cd $FRAMEWORK_PATH/flutter/packages/flutter + ../../bin/flutter test --local-engine=host_debug_unopt + - name: build_and_test_host_profile + compile_host_script: | + cd $ENGINE_PATH/src + ./flutter/tools/gn --runtime-mode profile --no-lto + ninja -C out/host_profile + test_host_script: cd $ENGINE_PATH/src && ./flutter/testing/run_tests.sh host_profile + - name: build_and_test_host_release + compile_host_script: | + cd $ENGINE_PATH/src + ./flutter/tools/gn --runtime-mode release --no-lto + ninja -C out/host_release + test_host_script: cd $ENGINE_PATH/src && ./flutter/testing/run_tests.sh host_release - name: build_android + get_android_sdk_script: | + echo 'solutions = [{"managed": False,"name": "src/flutter","url": "git@github.com:flutter/engine.git","deps_file": "DEPS", "custom_vars": {"download_windows_deps" : False,},},]' > $ENGINE_PATH/.gclient + cd $ENGINE_PATH/src + gclient sync + lint_host_script: | + cd $ENGINE_PATH/src/flutter/tools/android_lint + $ENGINE_PATH/src/third_party/dart/tools/sdks/dart-sdk/bin/pub get + $ENGINE_PATH/src/third_party/dart/tools/sdks/dart-sdk/bin/dart bin/main.dart compile_host_script: | cd $ENGINE_PATH/src ./flutter/tools/gn --android --unoptimized ninja -C out/android_debug_unopt mkdir javadoc_tmp ./flutter/tools/gen_javadoc.py --out-dir javadoc_tmp + - name: format_and_dart_test + format_script: cd $ENGINE_PATH/src/flutter && ./ci/format.sh + build_script: cd $ENGINE_PATH/src/flutter && ./ci/build.sh -format_and_dart_test_task: - container: - image: gcr.io/flutter-cirrus/build-engine-image:latest +task: + gce_instance: + image_project: flutter-cirrus + image_name: flutter-engine-windows-server-2016-core + zone: us-central1-a + platform: windows + cpu: 32 + memory: 32Gb + disk: 50 env: - CIRRUS_WORKING_DIR: "/tmp/github_repo" + # Cirrus is somehow not picking up the environment variables set in the VM image. + PATH: "c:/depot_tools;c:/MinGit/cmd;$PATH" + DEPOT_TOOLS_WIN_TOOLCHAIN: 0 + GYP_MSVS_OVERRIDE_PATH: "c:/Program Files (x86)/Microsoft Visual Studio/2017/Community" - replace_engine_script: | - cd $ENGINE_PATH/src - rm -r flutter - cp $CIRRUS_WORKING_DIR -r ./flutter + ENGINE_PATH: "c:/flutter/engine" + + # robocopy can return 1 for successful copy; suppress its error code. + # move somehow doesn't work as it complains that the file is being used by another process. + gclient_sync_script: | + robocopy %CIRRUS_WORKING_DIR% %ENGINE_PATH%/src/flutter /MIR || (cmd /s /c exit /b 0) + cd %ENGINE_PATH%/src gclient sync - format_script: cd $ENGINE_PATH/src/flutter && ./ci/format.sh - build_script: cd $ENGINE_PATH/src/flutter && ./ci/build.sh + matrix: + - name: build_windows_debug + compile_host_script: | + cd %ENGINE_PATH%/src + python flutter/tools/gn --runtime-mode debug --unoptimized + ninja -C out/host_debug_unopt + + - name: build_windows_debug_unopt + compile_host_script: | + cd %ENGINE_PATH%/src + python flutter/tools/gn --runtime-mode debug + ninja -C out/host_debug diff --git a/BUILD.gn b/BUILD.gn index 9bfa135468c01..8f4243d4b9936 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -4,6 +4,16 @@ import("$flutter_root/common/config.gni") +if (is_fuchsia) { + import("//build/fuchsia/sdk.gni") +} + +# Whether to build the dartdevc sdk, libraries, and source files +# required for the flutter web sdk. +declare_args() { + full_dart_sdk = false +} + group("flutter") { testonly = true @@ -18,12 +28,20 @@ group("flutter") { public_deps += [ "$flutter_root/shell/testing" ] } + if (is_fuchsia && using_fuchsia_sdk) { + public_deps += [ "$flutter_root/shell/platform/fuchsia" ] + } + if (!is_fuchsia && !is_fuchsia_host) { if (current_toolchain == host_toolchain) { public_deps += [ "$flutter_root/frontend_server", "//third_party/dart:create_sdk", ] + + if (full_dart_sdk) { + public_deps += [ "$flutter_root/web_sdk" ] + } } } @@ -39,8 +57,9 @@ group("flutter") { "$flutter_root/fml:fml_unittests", "$flutter_root/runtime:runtime_unittests", "$flutter_root/shell/common:shell_unittests", + "$flutter_root/shell/platform/common/cpp/client_wrapper:client_wrapper_unittests", "$flutter_root/shell/platform/embedder:embedder_unittests", - "$flutter_root/synchronization:synchronization_unittests", + "$flutter_root/shell/platform/glfw/client_wrapper:client_wrapper_glfw_unittests", "$flutter_root/third_party/txt:txt_unittests", ] @@ -54,6 +73,15 @@ config("config") { include_dirs = [ ".." ] } +config("export_dynamic_symbols") { + if (is_linux) { + inputs = [ + "$flutter_root/common/exported_symbols.sym", + ] + ldflags = [ "-Wl,--dynamic-list=" + rebase_path(inputs[0], root_build_dir) ] + } +} + group("dist") { testonly = true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aa1efa2bc0437..5a9aefa434773 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,18 +1,22 @@ Contributing to the Flutter engine ================================== -[![Build Status](https://cirrus-ci.com/flutter/engine.svg)](https://cirrus-ci.com/flutter/engine) +[![Build Status](https://api.cirrus-ci.com/github/flutter/engine.svg)][build_status] -_See also: [Flutter's code of conduct](https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md)_ +_See also: [Flutter's code of conduct][code_of_conduct]_ Welcome ------- -For an introduction to contributing to Flutter, see [our -contributor -guide](https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md). +For an introduction to contributing to Flutter, see [our contributor +guide][contrib_guide]. -For specific instructions regarding building Flutter's engine, see -[Setting up the Engine development -environment](https://github.com/flutter/flutter/wiki/Setting-up-the-Engine-development-environment) -on our wiki. Those instructions are part of the broader onboarding instructions described in the contributing guide. +For specific instructions regarding building Flutter's engine, see [Setting up +the Engine development environment][engine_dev_setup] on our wiki. Those +instructions are part of the broader onboarding instructions described in the +contributing guide. + +[build_status]: https://cirrus-ci.com/github/flutter/engine +[code_of_conduct]: https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md +[contrib_guide]: https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md +[engine_dev_setup]: https://github.com/flutter/flutter/wiki/Setting-up-the-Engine-development-environment diff --git a/DEPS b/DEPS index 1beaadf2c53b7..a1b2647f23afe 100644 --- a/DEPS +++ b/DEPS @@ -23,7 +23,7 @@ vars = { 'fuchsia_git': 'https://fuchsia.googlesource.com', 'github_git': 'https://github.com', 'skia_git': 'https://skia.googlesource.com', - 'skia_revision': '70ebd9ca0616f54450a38d4f0f952810595a441b', + 'skia_revision': '0c6daf034b11b0924b05abe441ffa892c7bc3c07', # When updating the Dart revision, ensure that all entries that are # dependencies of Dart are also updated to match the entries in the @@ -31,13 +31,13 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/master/DEPS. # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '71bee8f05eb40e2f3b49ed57b8f46421f4432179', + 'dart_revision': 'b2a3d1c31bee3e20efa8216b883f47620dd73273', # 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_args_tag': '1.4.4', 'dart_async_tag': '2.0.8', - 'dart_bazel_worker_tag': '0.1.14', + 'dart_bazel_worker_tag': 'bazel_worker-v0.1.20', 'dart_boolean_selector_tag': '1.0.4', 'dart_boringssl_gen_rev': 'bbf52f18f425e29b1185f2f6753bec02ed8c5880', 'dart_boringssl_rev': '702e2b6d3831486535e958f262a05c75a5cb312e', @@ -46,23 +46,23 @@ vars = { 'dart_collection_tag': '1.14.11', 'dart_convert_tag': '2.0.2', 'dart_crypto_tag': '2.0.6', - 'dart_csslib_tag': '0.14.4+1', - 'dart_dart2js_info_tag': '0.5.15', - 'dart_dart_style_tag': '1.2.2', - 'dart_dartdoc_tag': 'v0.28.0', + 'dart_csslib_tag': '0.15.0', + 'dart_dart2js_info_tag': '0.6.0', + 'dart_dart_style_tag': '1.2.7', + 'dart_dartdoc_tag': 'v0.28.2', 'dart_fixnum_tag': '0.10.9', 'dart_glob_tag': '1.1.7', - 'dart_html_tag': '0.13.3+2', + 'dart_html_tag': '0.14.0+1', 'dart_http_multi_server_tag': '2.0.5', - 'dart_http_parser_tag': '3.1.1', + 'dart_http_parser_tag': '3.1.3', 'dart_http_retry_tag': '0.1.1', - 'dart_http_tag': '0.12.0', + 'dart_http_tag': '0.12.0+2', 'dart_http_throttle_tag': '1.0.2', 'dart_intl_tag': '0.15.7', 'dart_json_rpc_2_tag': '2.0.9', - 'dart_linter_tag': '0.1.79', + 'dart_linter_tag': '0.1.88', 'dart_logging_tag': '0.11.3+2', - 'dart_markdown_tag': '2.0.2', + 'dart_markdown_tag': '2.0.3', 'dart_matcher_tag': '0.12.3', 'dart_mime_tag': '0.9.6+2', 'dart_mockito_tag': 'd39ac507483b9891165e422ec98d9fb480037c8b', @@ -70,14 +70,14 @@ vars = { 'dart_oauth2_tag': '1.2.1', 'dart_observatory_pub_packages_rev': '0894122173b0f98eb08863a7712e78407d4477bc', 'dart_package_config_tag': '1.0.5', - 'dart_package_resolver_tag': '1.0.4', + 'dart_package_resolver_tag': '1.0.10', 'dart_path_tag': '1.6.2', - 'dart_plugin_tag': 'f5b4b0e32d1406d62daccea030ba6457d14b1c47', + 'dart_pedantic_tag': 'v1.5.0', 'dart_pool_tag': '1.3.6', - 'dart_protobuf_tag': '0.9.0', - 'dart_pub_rev': '9f00679ef47bc79cadc18e143720ade6c06c0100', + 'dart_protobuf_rev': '7d34c9e4e552a4f66acce32e4344ae27756a1949', + 'dart_pub_rev': '8c363fe26f059c3063f1129adbb3c4e22a8ce954', 'dart_pub_semver_tag': '1.4.2', - 'dart_quiver_tag': '2.0.0+1', + 'dart_quiver-dart_tag': '2.0.0+1', 'dart_resource_rev': '2.1.5', 'dart_root_certificates_rev': '16ef64be64c7dfdff2b9f4b910726e635ccc519e', 'dart_shelf_packages_handler_tag': '1.0.4', @@ -86,16 +86,15 @@ vars = { 'dart_shelf_web_socket_tag': '0.2.2+3', 'dart_source_map_stack_trace_tag': '1.1.5', 'dart_source_maps_tag': '8af7cc1a1c3a193c1fba5993ce22a546a319c40e', - 'dart_source_span_tag': '1.4.1', + 'dart_source_span_tag': '1.5.5', 'dart_stack_trace_tag': '1.9.3', - 'dart_stream_channel_tag': '1.6.8', + 'dart_stream_channel_tag': '2.0.0', 'dart_string_scanner_tag': '1.0.3', 'dart_term_glyph_tag': '1.0.1', 'dart_test_reflective_loader_tag': '0.1.8', - 'dart_test_tag': '1.3.4', + 'dart_test_tag': 'test-v1.6.1', 'dart_typed_data_tag': '1.1.6', 'dart_usage_tag': '3.4.0', - 'dart_utf_tag': '0.9.0+5', 'dart_watcher_rev': '0.9.7+12', 'dart_web_socket_channel_tag': '1.0.9', 'dart_yaml_tag': '2.1.15', @@ -104,6 +103,12 @@ vars = { 'ios_tools_revision': '69b7c1b160e7107a6a98d948363772dc9caea46f', 'buildtools_revision': 'bac220c15490dcf7b7d8136f75100bbc77e8d217', + + # Checkout Android dependencies only on platforms where we build for Android targets. + 'download_android_deps': 'host_os == "mac" or host_os == "linux"', + + # Checkout Windows dependencies only if we are building on Windows. + 'download_windows_deps' : 'host_os == "win"', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -116,7 +121,7 @@ allowed_hosts = [ ] deps = { - 'src': 'https://github.com/flutter/buildroot.git' + '@' + '13ca742ec8b3d7761877197d74b003d3e646d805', + 'src': 'https://github.com/flutter/buildroot.git' + '@' + '224ebe0adaaf8463cc505a42c0e5eac870b2896e', # Fuchsia compatibility # @@ -125,13 +130,13 @@ deps = { # and not have to specific specific hashes. 'src/third_party/tonic': - Var('fuchsia_git') + '/tonic' + '@' + '02f9d8dd18dd259e3c5efe1fbe713819a730b6e0', + Var('fuchsia_git') + '/tonic' + '@' + 'bd27b4549199df72fcaeefd259ebc12a31c2e4ee', 'src/third_party/benchmark': Var('fuchsia_git') + '/third_party/benchmark' + '@' + '21f1eb3fe269ea43eba862bf6b699cde46587ade', 'src/third_party/googletest': - Var('fuchsia_git') + '/third_party/googletest' + '@' + '2072b0053d3537fa5e8d222e34c759987aae1320', + Var('fuchsia_git') + '/third_party/googletest' + '@' + '46d66506083fc3333d84c260e7bd2eb3816a917a', 'src/third_party/rapidjson': Var('fuchsia_git') + '/third_party/rapidjson' + '@' + '32d07c55db1bb6c2ae17cba4033491a667647753', @@ -145,6 +150,9 @@ deps = { 'src/third_party/libcxxabi': Var('fuchsia_git') + '/third_party/libcxxabi' + '@' + '1a9753522f1ae8d72848d365902f39e0d3d59a39', + 'src/third_party/glfw': + Var('fuchsia_git') + '/third_party/glfw' + '@' + '999f3556fdd80983b10051746264489f2cb1ef16', + # Chromium-style # # As part of integrating with Fuchsia, we should eventually remove all these @@ -159,32 +167,31 @@ deps = { 'src/third_party/icu': Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'c56c671998902fcc4fc9ace88c83daa99f980793', - 'src/third_party/dart': - Var('dart_git') + '/sdk.git' + '@' + Var('dart_revision'), - 'src/third_party/boringssl': Var('github_git') + '/dart-lang/boringssl_gen.git' + '@' + Var('dart_boringssl_gen_rev'), 'src/third_party/boringssl/src': 'https://boringssl.googlesource.com/boringssl.git' + '@' + Var('dart_boringssl_rev'), + 'src/third_party/dart': + Var('dart_git') + '/sdk.git' + '@' + Var('dart_revision'), + + # WARNING: Unused Dart dependencies in the list below till "WARNING:" marker are removed automatically - see create_updated_flutter_deps.py. + 'src/third_party/dart/third_party/observatory_pub_packages': Var('dart_git') + '/observatory_pub_packages.git' + '@' + Var('dart_observatory_pub_packages_rev'), - 'src/third_party/dart/third_party/pkg/oauth2': - Var('dart_git') + '/oauth2.git' + '@' + Var('dart_oauth2_tag'), - 'src/third_party/dart/third_party/pkg/args': Var('dart_git') + '/args.git' + '@' + Var('dart_args_tag'), 'src/third_party/dart/third_party/pkg/async': - Var('dart_git') + '/async.git' + '@' + Var('dart_async_tag'), + Var('dart_git') + '/async.git' + '@' + Var('dart_async_tag'), 'src/third_party/dart/third_party/pkg/bazel_worker': - Var('dart_git') + '/bazel_worker.git' + '@' + Var('dart_bazel_worker_tag'), + Var('dart_git') + '/bazel_worker.git' + '@' + Var('dart_bazel_worker_tag'), 'src/third_party/dart/third_party/pkg/boolean_selector': - Var('dart_git') + '/boolean_selector.git' + '@' + Var('dart_boolean_selector_tag'), + Var('dart_git') + '/boolean_selector.git' + '@' + Var('dart_boolean_selector_tag'), 'src/third_party/dart/third_party/pkg/charcode': Var('dart_git') + '/charcode.git' + '@' + Var('dart_charcode_tag'), @@ -210,12 +217,6 @@ deps = { 'src/third_party/dart/third_party/pkg/dartdoc': Var('dart_git') + '/dartdoc.git' + '@' + Var('dart_dartdoc_tag'), - 'src/third_party/dart/third_party/pkg/json_rpc_2': - Var('dart_git') + '/json_rpc_2.git' + '@' + Var('dart_json_rpc_2_tag'), - - 'src/third_party/dart/third_party/pkg/intl': - Var('dart_git') + '/intl.git' + '@' + Var('dart_intl_tag'), - 'src/third_party/dart/third_party/pkg/fixnum': Var('dart_git') + '/fixnum.git' + '@' + Var('dart_fixnum_tag'), @@ -228,6 +229,9 @@ deps = { 'src/third_party/dart/third_party/pkg/http': Var('dart_git') + '/http.git' + '@' + Var('dart_http_tag'), + 'src/third_party/dart/third_party/pkg/http_multi_server': + Var('dart_git') + '/http_multi_server.git' + '@' + Var('dart_http_multi_server_tag'), + 'src/third_party/dart/third_party/pkg/http_parser': Var('dart_git') + '/http_parser.git' + '@' + Var('dart_http_parser_tag'), @@ -237,15 +241,18 @@ deps = { 'src/third_party/dart/third_party/pkg/http_throttle': Var('dart_git') + '/http_throttle.git' + '@' + Var('dart_http_throttle_tag'), - 'src/third_party/dart/third_party/pkg/http_multi_server': - Var('dart_git') + '/http_multi_server.git' + '@' + Var('dart_http_multi_server_tag'), + 'src/third_party/dart/third_party/pkg/intl': + Var('dart_git') + '/intl.git' + '@' + Var('dart_intl_tag'), - 'src/third_party/dart/third_party/pkg/logging': - Var('dart_git') + '/logging.git' + '@' + Var('dart_logging_tag'), + 'src/third_party/dart/third_party/pkg/json_rpc_2': + Var('dart_git') + '/json_rpc_2.git' + '@' + Var('dart_json_rpc_2_tag'), 'src/third_party/dart/third_party/pkg/linter': Var('dart_git') + '/linter.git' + '@' + Var('dart_linter_tag'), + 'src/third_party/dart/third_party/pkg/logging': + Var('dart_git') + '/logging.git' + '@' + Var('dart_logging_tag'), + 'src/third_party/dart/third_party/pkg/markdown': Var('dart_git') + '/markdown.git' + '@' + Var('dart_markdown_tag'), @@ -261,32 +268,29 @@ deps = { 'src/third_party/dart/third_party/pkg/mustache': Var('dart_git') + '/external/github.com/xxgreg/mustache' + '@' + Var('dart_mustache_tag'), - 'src/third_party/dart/third_party/pkg_tested/package_config': - Var('dart_git') + '/package_config.git' + '@' + Var('dart_package_config_tag'), - - 'src/third_party/dart/third_party/pkg_tested/package_resolver': - Var('dart_git') + '/package_resolver.git' + '@' + Var('dart_package_resolver_tag'), + 'src/third_party/dart/third_party/pkg/oauth2': + Var('dart_git') + '/oauth2.git' + '@' + Var('dart_oauth2_tag'), 'src/third_party/dart/third_party/pkg/path': Var('dart_git') + '/path.git' + '@' + Var('dart_path_tag'), + 'src/third_party/dart/third_party/pkg/pedantic': + Var('dart_git') + '/pedantic.git' + '@' + Var('dart_pedantic_tag'), + 'src/third_party/dart/third_party/pkg/pool': Var('dart_git') + '/pool.git' + '@' + Var('dart_pool_tag'), - 'src/third_party/dart/third_party/pkg/plugin': - Var('dart_git') + '/plugin.git' + '@' + Var('dart_plugin_tag'), - 'src/third_party/dart/third_party/pkg/protobuf': - Var('dart_git') + '/protobuf.git' + '@' + Var('dart_protobuf_tag'), - - 'src/third_party/dart/third_party/pkg/pub_semver': - Var('dart_git') + '/pub_semver.git' + '@' + Var('dart_pub_semver_tag'), + Var('dart_git') + '/protobuf.git' + '@' + Var('dart_protobuf_rev'), 'src/third_party/dart/third_party/pkg/pub': Var('dart_git') + '/pub.git' + '@' + Var('dart_pub_rev'), + 'src/third_party/dart/third_party/pkg/pub_semver': + Var('dart_git') + '/pub_semver.git' + '@' + Var('dart_pub_semver_tag'), + 'src/third_party/dart/third_party/pkg/quiver': - Var('chromium_git') + '/external/github.com/google/quiver-dart' + '@' + Var('dart_quiver_tag'), + Var('chromium_git') + '/external/github.com/google/quiver-dart.git' + '@' + Var('dart_quiver-dart_tag'), 'src/third_party/dart/third_party/pkg/resource': Var('dart_git') + '/resource.git' + '@' + Var('dart_resource_rev'), @@ -303,41 +307,35 @@ deps = { 'src/third_party/dart/third_party/pkg/shelf_web_socket': Var('dart_git') + '/shelf_web_socket.git' + '@' + Var('dart_shelf_web_socket_tag'), - 'src/third_party/dart/third_party/pkg/source_span': - Var('dart_git') + '/source_span.git' + '@' + Var('dart_source_span_tag'), - 'src/third_party/dart/third_party/pkg/source_map_stack_trace': Var('dart_git') + '/source_map_stack_trace.git' + '@' + Var('dart_source_map_stack_trace_tag'), 'src/third_party/dart/third_party/pkg/source_maps': Var('dart_git') + '/source_maps.git' + '@' + Var('dart_source_maps_tag'), - 'src/third_party/dart/third_party/pkg/string_scanner': - Var('dart_git') + '/string_scanner.git' + '@' + Var('dart_string_scanner_tag'), - - 'src/third_party/dart/third_party/pkg/stream_channel': - Var('dart_git') + '/stream_channel.git' + '@' + Var('dart_stream_channel_tag'), + 'src/third_party/dart/third_party/pkg/source_span': + Var('dart_git') + '/source_span.git' + '@' + Var('dart_source_span_tag'), 'src/third_party/dart/third_party/pkg/stack_trace': Var('dart_git') + '/stack_trace.git' + '@' + Var('dart_stack_trace_tag'), - 'src/third_party/dart/third_party/pkg_tested/dart_style': - Var('dart_git') + '/dart_style.git' + '@' + Var('dart_dart_style_tag'), + 'src/third_party/dart/third_party/pkg/stream_channel': + Var('dart_git') + '/stream_channel.git' + '@' + Var('dart_stream_channel_tag'), - 'src/third_party/dart/third_party/pkg/typed_data': - Var('dart_git') + '/typed_data.git' + '@' + Var('dart_typed_data_tag'), + 'src/third_party/dart/third_party/pkg/string_scanner': + Var('dart_git') + '/string_scanner.git' + '@' + Var('dart_string_scanner_tag'), 'src/third_party/dart/third_party/pkg/term_glyph': Var('dart_git') + '/term_glyph.git' + '@' + Var('dart_term_glyph_tag'), - 'src/third_party/dart/third_party/pkg/test_reflective_loader': - Var('dart_git') + '/test_reflective_loader.git' + '@' + Var('dart_test_reflective_loader_tag'), - 'src/third_party/dart/third_party/pkg/test': Var('dart_git') + '/test.git' + '@' + Var('dart_test_tag'), - 'src/third_party/dart/third_party/pkg/utf': - Var('dart_git') + '/utf.git' + '@' + Var('dart_utf_tag'), + 'src/third_party/dart/third_party/pkg/test_reflective_loader': + Var('dart_git') + '/test_reflective_loader.git' + '@' + Var('dart_test_reflective_loader_tag'), + + 'src/third_party/dart/third_party/pkg/typed_data': + Var('dart_git') + '/typed_data.git' + '@' + Var('dart_typed_data_tag'), 'src/third_party/dart/third_party/pkg/usage': Var('dart_git') + '/usage.git' + '@' + Var('dart_usage_tag'), @@ -351,11 +349,22 @@ deps = { 'src/third_party/dart/third_party/pkg/yaml': Var('dart_git') + '/yaml.git' + '@' + Var('dart_yaml_tag'), + 'src/third_party/dart/third_party/pkg_tested/dart_style': + Var('dart_git') + '/dart_style.git' + '@' + Var('dart_dart_style_tag'), + + 'src/third_party/dart/third_party/pkg_tested/package_config': + Var('dart_git') + '/package_config.git' + '@' + Var('dart_package_config_tag'), + + 'src/third_party/dart/third_party/pkg_tested/package_resolver': + Var('dart_git') + '/package_resolver.git' + '@' + Var('dart_package_resolver_tag'), + + # WARNING: end of dart dependencies list that is cleaned up automatically - see create_updated_flutter_deps.py. + 'src/third_party/colorama/src': Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', 'src/third_party/freetype2': - Var('fuchsia_git') + '/third_party/freetype2' + '@' + 'a10b062df0c8958d69377aa04ea6554a9961a111', + Var('fuchsia_git') + '/third_party/freetype2' + '@' + 'edab12c07ac05d1185616688f338b1ad15936796', 'src/third_party/root_certificates': Var('dart_git') + '/root_certificates.git' + '@' + Var('dart_root_certificates_rev'), @@ -364,11 +373,17 @@ deps = { Var('skia_git') + '/skia.git' + '@' + Var('skia_revision'), 'src/third_party/libjpeg-turbo': - Var('fuchsia_git') + '/third_party/libjpeg-turbo' + '@' + '9587e51cf946f1a1d19bb596bc31ba4e6c9d8893', + Var('fuchsia_git') + '/third_party/libjpeg-turbo' + '@' + '0fb821f3b2e570b2783a94ccd9a2fb1f4916ae9f', 'src/third_party/libwebp': Var('chromium_git') + '/webm/libwebp.git' + '@' + '0.6.0', + 'src/third_party/wuffs': + Var('fuchsia_git') + '/third_party/wuffs' + '@' + 'a71538baa8f1f4053176c0d9f31bc12fd4e8e71b', + + 'src/third_party/fontconfig/src': + Var('chromium_git') + '/external/fontconfig.git' + '@' + 'c336b8471877371f0190ba06f7547c54e2b890ba', + 'src/third_party/gyp': Var('chromium_git') + '/external/gyp.git' + '@' + '4801a5331ae62da9769a327f11c4213d32fb0dad', @@ -378,11 +393,116 @@ deps = { 'src/third_party/pkg/when': Var('dart_git') + '/when.git' + '@' + '0.2.0', -} -recursedeps = [ - 'src/buildtools', -] + 'src/third_party/android_tools/ndk': { + 'packages': [ + { + 'package': 'flutter/android/ndk/${{platform}}', + 'version': 'version:r19b' + } + ], + 'condition': 'download_android_deps', + 'dep_type': 'cipd', + }, + + 'src/third_party/android_tools/sdk/build-tools': { + 'packages': [ + { + 'package': 'flutter/android/sdk/build-tools/${{platform}}', + 'version': 'version:28.0.3' + } + ], + 'condition': 'download_android_deps', + 'dep_type': 'cipd', + }, + + 'src/third_party/android_tools/sdk/platform-tools': { + 'packages': [ + { + 'package': 'flutter/android/sdk/platform-tools/${{platform}}', + 'version': 'version:28.0.1' + } + ], + 'condition': 'download_android_deps', + 'dep_type': 'cipd', + }, + + 'src/third_party/android_tools/sdk/platforms': { + 'packages': [ + { + 'package': 'flutter/android/sdk/platforms', + 'version': 'version:28r6' + } + ], + 'condition': 'download_android_deps', + 'dep_type': 'cipd', + }, + + 'src/third_party/android_tools/sdk/tools': { + 'packages': [ + { + 'package': 'flutter/android/sdk/tools/${{platform}}', + 'version': 'version:26.1.1' + } + ], + 'condition': 'download_android_deps', + 'dep_type': 'cipd', + }, + + 'src/third_party/dart/tools/sdks': { + 'packages': [ + { + 'package': 'dart/dart-sdk/${{platform}}', + 'version': 'version:2.2.0' + } + ], + 'dep_type': 'cipd', + }, + + # Get the SDK from https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core at the 'latest' tag + # Get the toolchain from https://chrome-infra-packages.appspot.com/p/fuchsia/clang at the 'goma' tag + + 'src/fuchsia/sdk/mac': { + 'packages': [ + { + 'package': 'fuchsia/sdk/core/mac-amd64', + 'version': 'jlQvNeRMq6X81_VYiFI_Ol311YCXak0xACebeb8f6TcC' + } + ], + 'condition': 'host_os == "mac"', + 'dep_type': 'cipd', + }, + 'src/fuchsia/toolchain/mac': { + 'packages': [ + { + 'package': 'fuchsia/clang/mac-amd64', + 'version': '4OfgjQg8g3Ztj2OYJ4Zlz9Q6DGYjOTuHh3G8MSMhxg4C' + } + ], + 'condition': 'host_os == "mac"', + 'dep_type': 'cipd', + }, + 'src/fuchsia/sdk/linux': { + 'packages': [ + { + 'package': 'fuchsia/sdk/core/linux-amd64', + 'version': '9-zyx3CzWylM-x9RYdL5UTT9uU-sl_0ysOCcEGCtot0C' + } + ], + 'condition': 'host_os == "linux"', + 'dep_type': 'cipd', + }, + 'src/fuchsia/toolchain/linux': { + 'packages': [ + { + 'package': 'fuchsia/clang/linux-amd64', + 'version': 'WPg0zzXLyTjFNrOrz4uA5vPaXUuEYvTJ5DPyYdiaN3MC' + } + ], + 'condition': 'host_os == "linux"', + 'dep_type': 'cipd', + }, +} hooks = [ { @@ -399,83 +519,14 @@ hooks = [ { # Update the Windows toolchain if necessary. 'name': 'win_toolchain', + 'condition': 'download_windows_deps', 'pattern': '.', 'action': ['python', 'src/build/vs_toolchain.py', 'update'], }, - { - # Pull dart sdk if needed - # this will be used by android_tools - 'name': 'dart', - 'pattern': '.', - 'action': ['python', 'src/tools/dart/update.py'], - }, - { - 'name': 'prepare_android_downloader', - 'pattern': '.', - 'cwd': 'src/tools/android/android_sdk_downloader', - 'condition': 'host_os == "linux" or host_os == "mac"', - 'action': [ - '../../../third_party/dart/tools/sdks/dart-sdk/bin/pub', # this hook _must_ be run _after_ the dart hook. - 'get' - ], - }, - # TODO(dnfield): This can be enabled when we actually support building - # the android engine on windows. For now there's no sense in having - # windows clients download bits they don't need. - # see: https://github.com/flutter/flutter/issues/13841 - # { - # 'name': 'prepare_android_downloader_win', - # 'pattern': '.', - # 'cwd': 'src\\tools\\android\\android_sdk_downloader', - # 'condition': 'host_os == "win"', - # 'action': [ - # '..\\..\\..\\third_party\\dart\\tools\\sdks\\dart-sdk\\bin\\pub.bat', # this hook _must_ be run _after_ the dart hook. - # 'get' - # ], - # }, - { - 'name': 'download_android_tools', - 'pattern': '.', - 'condition': 'host_os == "mac" or host_os == "linux"', - 'action': [ - 'src/third_party/dart/tools/sdks/dart-sdk/bin/dart', # this hook _must_ be run _after_ the dart hook. - '--enable-asserts', - 'src/tools/android/android_sdk_downloader/lib/main.dart', - '-y', # Accept licenses - '--out=src/third_party/android_tools', - '--platform=28', - '--platform-revision=6', - '--build-tools-version=28.0.3', - '--platform-tools-version=28.0.1', - '--tools-version=26.1.1', - '--ndk-version=19.0.5232133' - ], - }, - # TODO(dnfield): This can be enabled when we actually support building - # the android engine on windows. For now there's no sense in having - # windows clients download bits they don't need. - # see: https://github.com/flutter/flutter/issues/13841 - # { - # 'name': 'download_android_tools_win', - # 'pattern': '.', - # 'condition': 'host_os == "win"', - # 'action': [ - # 'src\\third_party\\dart\\tools\\sdks\\dart-sdk\\bin\\dart.exe', # this hook _must_ be run _after_ the dart hook. - # '--enable-asserts', - # 'src\\tools\\android\\android_sdk_downloader\\lib\\main.dart', - # '-y', # Accept licenses - # '--out=src\\third_party\\android_tools', - # '--platform=28', - # '--platform-revision=6', - # '--build-tools-version=28.0.3', - # '--platform-tools-version=28.0.1', - # '--tools-version=26.1.1', - # '--ndk-version=19.0.5232133' - # ], - # }, { 'name': 'download_android_support', 'pattern': '.', + 'condition': 'download_android_deps', 'action': [ 'python', 'src/flutter/tools/android_support/download_android_support.py', @@ -507,18 +558,19 @@ hooks = [ ], }, { - "name": "7zip", - "pattern": ".", - "action": [ - "download_from_google_storage", - "--no_auth", - "--no_resume", - "--bucket", - "dart-dependencies", - "--platform=win32", - "--extract", - "-s", - "src/third_party/dart/third_party/7zip.tar.gz.sha1", + 'name': '7zip', + 'pattern': '.', + 'condition': 'download_windows_deps', + 'action': [ + 'download_from_google_storage', + '--no_auth', + '--no_resume', + '--bucket', + 'dart-dependencies', + '--platform=win32', + '--extract', + '-s', + 'src/third_party/dart/third_party/7zip.tar.gz.sha1', ], }, ] diff --git a/README.md b/README.md index 8eedc223a79fb..00187bd4c4ba9 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Flutter is optimized for today's, and tomorrow's, mobile devices. We are focused on low-latency input and high frame rates on Android and iOS. The Flutter Engine is a portable runtime for hosting -[Flutter](https://flutter.io) applications. It implements Flutter's core +[Flutter](https://flutter.dev) applications. It implements Flutter's core libraries, including animation and graphics, file and network I/O, accessibility support, plugin architecture, and a Dart runtime and compile toolchain. Most developers will interact with Flutter via the [Flutter @@ -16,9 +16,9 @@ reactive framework, and a rich set of platform, layout and foundation widgets. If you are new to Flutter, then you will find more general information on the Flutter project, including tutorials and samples, on our Web -site at [flutter.io](https://flutter.io). For specific information +site at [Flutter.dev](https://flutter.dev). For specific information about Flutter's APIs, consider our API reference which can be found at -the [docs.flutter.io](https://docs.flutter.io/). +the [docs.flutter.dev](https://docs.flutter.dev/). If you intend to contribute to Flutter, welcome! You are encouraged to start with [our contributor diff --git a/analysis_options.yaml b/analysis_options.yaml index 699ca970ef474..e3ab5fe94c2c1 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -100,7 +100,7 @@ linter: - prefer_const_literals_to_create_immutables # - prefer_constructors_over_static_methods # not yet tested - prefer_contains - # - prefer_equal_for_default_values # not yet tested + - prefer_equal_for_default_values # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods # - prefer_final_fields # DIFFERENT FROM FLUTTER/FLUTTER - prefer_final_locals @@ -118,15 +118,16 @@ linter: - slash_for_doc_comments # - sort_constructors_first # DIFFERENT FROM FLUTTER/FLUTTER - sort_unnamed_constructors_first - - super_goes_last - test_types_in_equals - throw_in_finally # - type_annotate_public_apis # subset of always_specify_types - type_init_formals # - unawaited_futures # https://github.com/flutter/flutter/issues/5793 - unnecessary_brace_in_string_interps + - unnecessary_const - unnecessary_getters_setters # - unnecessary_lambdas # https://github.com/dart-lang/linter/issues/498 + - unnecessary_new - unnecessary_null_aware_assignments - unnecessary_null_in_if_null_operators - unnecessary_overrides diff --git a/assets/asset_manager.cc b/assets/asset_manager.cc index 610bd10a14a3f..60d169a31ebb2 100644 --- a/assets/asset_manager.cc +++ b/assets/asset_manager.cc @@ -7,7 +7,7 @@ #include "flutter/assets/directory_asset_bundle.h" #include "flutter/fml/trace_event.h" -namespace blink { +namespace flutter { AssetManager::AssetManager() = default; @@ -29,7 +29,7 @@ void AssetManager::PushBack(std::unique_ptr resolver) { resolvers_.push_back(std::move(resolver)); } -// |blink::AssetResolver| +// |AssetResolver| std::unique_ptr AssetManager::GetAsMapping( const std::string& asset_name) const { if (asset_name.size() == 0) { @@ -47,9 +47,9 @@ std::unique_ptr AssetManager::GetAsMapping( return nullptr; } -// |blink::AssetResolver| +// |AssetResolver| bool AssetManager::IsValid() const { return resolvers_.size() > 0; } -} // namespace blink +} // namespace flutter diff --git a/assets/asset_manager.h b/assets/asset_manager.h index 42ffa9b1053c4..2278742f50113 100644 --- a/assets/asset_manager.h +++ b/assets/asset_manager.h @@ -13,7 +13,7 @@ #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_counted.h" -namespace blink { +namespace flutter { class AssetManager final : public AssetResolver { public: @@ -25,10 +25,10 @@ class AssetManager final : public AssetResolver { void PushBack(std::unique_ptr resolver); - // |blink::AssetResolver| + // |AssetResolver| bool IsValid() const override; - // |blink::AssetResolver| + // |AssetResolver| std::unique_ptr GetAsMapping( const std::string& asset_name) const override; @@ -38,6 +38,6 @@ class AssetManager final : public AssetResolver { FML_DISALLOW_COPY_AND_ASSIGN(AssetManager); }; -} // namespace blink +} // namespace flutter #endif // FLUTTER_ASSETS_ASSET_MANAGER_H_ diff --git a/assets/asset_resolver.h b/assets/asset_resolver.h index c49b8fb99a868..cbfadd2ada455 100644 --- a/assets/asset_resolver.h +++ b/assets/asset_resolver.h @@ -11,7 +11,7 @@ #include "flutter/fml/macros.h" #include "flutter/fml/mapping.h" -namespace blink { +namespace flutter { class AssetResolver { public: @@ -29,6 +29,6 @@ class AssetResolver { FML_DISALLOW_COPY_AND_ASSIGN(AssetResolver); }; -} // namespace blink +} // namespace flutter #endif // FLUTTER_ASSETS_ASSET_RESOLVER_H_ diff --git a/assets/directory_asset_bundle.cc b/assets/directory_asset_bundle.cc index 2f39535314d91..734e678bd3904 100644 --- a/assets/directory_asset_bundle.cc +++ b/assets/directory_asset_bundle.cc @@ -10,7 +10,7 @@ #include "flutter/fml/file.h" #include "flutter/fml/mapping.h" -namespace blink { +namespace flutter { DirectoryAssetBundle::DirectoryAssetBundle(fml::UniqueFD descriptor) : descriptor_(std::move(descriptor)) { @@ -22,12 +22,12 @@ DirectoryAssetBundle::DirectoryAssetBundle(fml::UniqueFD descriptor) DirectoryAssetBundle::~DirectoryAssetBundle() = default; -// |blink::AssetResolver| +// |AssetResolver| bool DirectoryAssetBundle::IsValid() const { return is_valid_; } -// |blink::AssetResolver| +// |AssetResolver| std::unique_ptr DirectoryAssetBundle::GetAsMapping( const std::string& asset_name) const { if (!is_valid_) { @@ -45,4 +45,4 @@ std::unique_ptr DirectoryAssetBundle::GetAsMapping( return mapping; } -} // namespace blink +} // namespace flutter diff --git a/assets/directory_asset_bundle.h b/assets/directory_asset_bundle.h index 041c301e8730a..0a0a94c7aba15 100644 --- a/assets/directory_asset_bundle.h +++ b/assets/directory_asset_bundle.h @@ -10,7 +10,7 @@ #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/unique_fd.h" -namespace blink { +namespace flutter { class DirectoryAssetBundle : public AssetResolver { public: @@ -22,16 +22,16 @@ class DirectoryAssetBundle : public AssetResolver { const fml::UniqueFD descriptor_; bool is_valid_ = false; - // |blink::AssetResolver| + // |AssetResolver| bool IsValid() const override; - // |blink::AssetResolver| + // |AssetResolver| std::unique_ptr GetAsMapping( const std::string& asset_name) const override; FML_DISALLOW_COPY_AND_ASSIGN(DirectoryAssetBundle); }; -} // namespace blink +} // namespace flutter #endif // FLUTTER_ASSETS_DIRECTORY_ASSET_BUNDLE_H_ diff --git a/assets/zip_asset_store.cc b/assets/zip_asset_store.cc index 97228f96087a8..44815a96b5c17 100644 --- a/assets/zip_asset_store.cc +++ b/assets/zip_asset_store.cc @@ -16,7 +16,7 @@ #include "flutter/fml/trace_event.h" -namespace blink { +namespace flutter { void UniqueUnzipperTraits::Free(void* file) { unzClose(file); @@ -33,12 +33,12 @@ UniqueUnzipper ZipAssetStore::CreateUnzipper() const { return UniqueUnzipper{::unzOpen2(file_path_.c_str(), nullptr)}; } -// |blink::AssetResolver| +// |AssetResolver| bool ZipAssetStore::IsValid() const { return stat_cache_.size() > 0; } -// |blink::AssetResolver| +// |AssetResolver| std::unique_ptr ZipAssetStore::GetAsMapping( const std::string& asset_name) const { TRACE_EVENT1("flutter", "ZipAssetStore::GetAsMapping", "name", @@ -126,4 +126,4 @@ void ZipAssetStore::BuildStatCache() { } while (unzGoToNextFile(unzipper.get()) == UNZ_OK); } -} // namespace blink +} // namespace flutter diff --git a/assets/zip_asset_store.h b/assets/zip_asset_store.h index b8b66a7d4f5ea..c3bba3f412c34 100644 --- a/assets/zip_asset_store.h +++ b/assets/zip_asset_store.h @@ -11,7 +11,7 @@ #include "flutter/fml/macros.h" #include "third_party/zlib/contrib/minizip/unzip.h" -namespace blink { +namespace flutter { struct UniqueUnzipperTraits { static inline void* InvalidValue() { return nullptr; } @@ -40,10 +40,10 @@ class ZipAssetStore final : public AssetResolver { mutable std::map stat_cache_; - // |blink::AssetResolver| + // |AssetResolver| bool IsValid() const override; - // |blink::AssetResolver| + // |AssetResolver| std::unique_ptr GetAsMapping( const std::string& asset_name) const override; @@ -54,6 +54,6 @@ class ZipAssetStore final : public AssetResolver { FML_DISALLOW_COPY_AND_ASSIGN(ZipAssetStore); }; -} // namespace blink +} // namespace flutter #endif // FLUTTER_ASSETS_ZIP_ASSET_STORE_H_ diff --git a/build/dart/rules.gni b/build/dart/rules.gni index d1b66255e987d..9ce67a449b208 100644 --- a/build/dart/rules.gni +++ b/build/dart/rules.gni @@ -44,7 +44,8 @@ template("dart_pkg_helper") { sdk_ext_mappings += invoker.sdk_ext_mappings } - script = rebase_path("$flutter_root/build/dart/tools/dart_pkg.py", ".", "//") + script = + rebase_path("$flutter_root/build/dart/tools/dart_pkg.py", ".", "//") entrypoints = [] if (defined(invoker.apps)) { @@ -61,7 +62,8 @@ template("dart_pkg_helper") { if (defined(invoker.sources)) { sources += invoker.sources } else if (defined(invoker.pkg_dir)) { - list_script = rebase_path("$flutter_root/build/dart/tools/ls.py", ".", "//") + list_script = + rebase_path("$flutter_root/build/dart/tools/ls.py", ".", "//") extra_flags += [ "--read_only" ] ls_sources = exec_script(list_script, [ @@ -113,7 +115,9 @@ template("dart_pkg") { pubspec_yaml_path = rebase_path("pubspec.yaml") } dart_package_name_script = - rebase_path("$flutter_root/build/dart/tools/dart_package_name.py", ".", "//") + rebase_path("$flutter_root/build/dart/tools/dart_package_name.py", + ".", + "//") dart_package_name = exec_script(dart_package_name_script, [ "--pubspec", diff --git a/build/git_revision.py b/build/git_revision.py index c571ee823cb0c..3c16eb58e4a26 100755 --- a/build/git_revision.py +++ b/build/git_revision.py @@ -31,11 +31,10 @@ def main(): '-C', repository, 'rev-parse', - '--short', 'HEAD', ]) - print version.strip() + print (version.strip()) return 0 diff --git a/build/install-build-deps-linux-desktop.sh b/build/install-build-deps-linux-desktop.sh new file mode 100755 index 0000000000000..ef24ad5d95cf5 --- /dev/null +++ b/build/install-build-deps-linux-desktop.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# 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. + +# Installs the dependencies necessary to build the Linux Flutter shell, beyond +# those installed by install-build-deps.sh. + +set -e + +sudo apt-get -y install libgtk-3-dev libx11-dev diff --git a/ci/analyze.sh b/ci/analyze.sh index 09bf3e12f3993..33d930238209a 100755 --- a/ci/analyze.sh +++ b/ci/analyze.sh @@ -1,10 +1,15 @@ #!/bin/bash echo "Analyzing dart:ui library..." + +echo "Using analyzer from `which dartanalyzer`" + +dartanalyzer --version + RESULTS=`dartanalyzer \ --options flutter/analysis_options.yaml \ - out/host_debug_unopt/gen/sky/bindings/dart_ui/ui.dart \ + "$1out/host_debug_unopt/gen/sky/bindings/dart_ui/ui.dart" \ 2>&1 \ - | grep -Ev "No issues found!" \ + | grep -Ev "No issues found!" \ | grep -Ev "Analyzing.+out/host_debug_unopt/gen/sky/bindings/dart_ui/ui\.dart"` echo "$RESULTS" diff --git a/ci/build.sh b/ci/build.sh index 57699445121c1..6e63dd9c9fd62 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -2,9 +2,10 @@ set -ex PATH="$HOME/depot_tools:$PATH" - cd .. +PATH=$(pwd)/third_party/dart/tools/sdks/dart-sdk/bin:$PATH + # Build the dart UI files flutter/tools/gn --unoptimized ninja -C out/host_debug_unopt generate_dart_ui @@ -12,3 +13,9 @@ ninja -C out/host_debug_unopt generate_dart_ui # Analyze the dart UI flutter/ci/analyze.sh flutter/ci/licenses.sh + +# Check that dart libraries conform +cd flutter/web_sdk +pub get +cd .. +dart web_sdk/test/api_conform_test.dart diff --git a/ci/check_gn_format.py b/ci/check_gn_format.py new file mode 100755 index 0000000000000..528287452cd66 --- /dev/null +++ b/ci/check_gn_format.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# 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 sys +import subprocess +import os +import argparse +import errno +import shutil + +def GetGNFiles(directory): + directory = os.path.abspath(directory) + gn_files = [] + assert os.path.exists(directory), "Directory must exist %s" % directory + for root, dirs, files in os.walk(directory): + for file in files: + if file.endswith(".gn") or file.endswith(".gni"): + gn_files.append(os.path.join(root, file)) + return gn_files + +def main(): + parser = argparse.ArgumentParser(); + + parser.add_argument('--gn-binary', dest='gn_binary', required=True, type=str) + parser.add_argument('--dry-run', dest='dry_run', required=True, type=bool) + parser.add_argument('--root-directory', dest='root_directory', required=True, type=str) + + args = parser.parse_args() + + gn_binary = os.path.abspath(args.gn_binary) + assert os.path.exists(gn_binary), "GN Binary must exist %s" % gn_binary + + gn_command = [ gn_binary, 'format'] + + if args.dry_run: + gn_command.append('--dry-run') + + + for gn_file in GetGNFiles(args.root_directory): + if subprocess.call(gn_command + [ gn_file ]) != 0: + print "ERROR: '%s' is incorrectly formatted." % os.path.relpath(gn_file, args.root_directory) + print "Format the same with 'gn format' using the 'gn' binary in //buildtools." + print "Or, run ./ci/check_gn_format.py with '--dry-run false'" + return -1 + + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/ci/docker/build/Dockerfile b/ci/docker/build/Dockerfile index bf1a470f0e4aa..890b65a588265 100644 --- a/ci/docker/build/Dockerfile +++ b/ci/docker/build/Dockerfile @@ -17,9 +17,4 @@ RUN gclient sync WORKDIR $ENGINE_PATH/src RUN ./build/install-build-deps.sh --no-prompt RUN ./build/install-build-deps-android.sh --no-prompt - -WORKDIR $HOME/dart -RUN wget https://storage.googleapis.com/dart-archive/channels/dev/release/2.1.0-dev.7.1/sdk/dartsdk-linux-x64-release.zip -RUN unzip dartsdk-linux-x64-release.zip -ENV PATH $PATH:$HOME/dart/dart-sdk/bin - +RUN ./flutter/build/install-build-deps-linux-desktop.sh diff --git a/ci/docker/windows_build/README.md b/ci/docker/windows_build/README.md new file mode 100644 index 0000000000000..30298defa3166 --- /dev/null +++ b/ci/docker/windows_build/README.md @@ -0,0 +1,8 @@ +This directory should include scripts to build the docker container image used +for building flutter/engine in our CI system (currently [Cirrus](cirrus-ci.org)) +using Windows. + +So far we're still waiting GKE to have Kubernetes 1.14 and Windows containers. + +Before that, we use GCE Windows VMs for our CI tests. This directory includes +scripts for preparing that VM. diff --git a/ci/docker/windows_build/prepare_windows_server_2016_core.ps1 b/ci/docker/windows_build/prepare_windows_server_2016_core.ps1 new file mode 100644 index 0000000000000..f11c1b7a53e37 --- /dev/null +++ b/ci/docker/windows_build/prepare_windows_server_2016_core.ps1 @@ -0,0 +1,68 @@ +# The following powershell script prepares the VM image +# flutter-engine-windows-server-2016-core used by Flutter engine's +# build_windows presubmit tests (see .cirrus.yml). +# +# The exact step of generating the VM image is: +# 1. Create a "Windows Server 2016 Datacenter Core" GCE instance with 50GB disk +# 2. RDP into that GCE instance to run this script with powershell +# (e.g., `powershell -File prepare_windows_server_2016_core.ps1`) +# 3. Shutdown the instance and take an image of that instance +# +# Note that ` is the escape character in powershell. + +# Install visual studio 2017 +curl https://aka.ms/vs/15/release/vs_community.exe -o vs_community.exe +./vs_community.exe --passive --wait ` + --add Microsoft.VisualStudio.Workload.NativeCrossPlat ` + --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended + +# Install debugger tools +curl https://download.microsoft.com/download/5/C/3/5C3770A3-12B4-4DB4-BAE7-99C624EB32AD/windowssdk/winsdksetup.exe ` + -o winsdksetup.exe +./winsdksetup.exe /features OptionId.WindowsDesktopDebuggers /q + +# Download depot tools +curl https://storage.googleapis.com/chrome-infra/depot_tools.zip ` + -o depot_tools.zip +Expand-Archive -LiteralPath depot_tools.zip -DestinationPath c:/depot_tools + +# Download git. Although depot_tools has its own git.bat, this is needed for +# Flutter engine's gn to run correctly. +# +# Somehow, curl can't get the MinGit from github. Fortunately, taobo works. +curl https://npm.taobao.org/mirrors/git-for-windows/v2.21.0.windows.1/MinGit-2.21.0-64-bit.zip ` + -o MinGit.zip +Expand-Archive -LiteralPath MinGit.zip -DestinationPath c:/MinGit + +# Restarting the terminal (or even the whole VM) is required to let following +# environment variables to take effect. +setx path "c:/depot_tools/;c:/MinGit/cmd;${env:path}" +setx DEPOT_TOOLS_WIN_TOOLCHAIN 0 +setx GYP_MSVS_OVERRIDE_PATH "c:/Program Files (x86)/Microsoft Visual Studio/2017/Community" + +mkdir c:/flutter/engine +curl https://raw.githubusercontent.com/flutter/engine/master/ci/docker/build/engine_gclient ` + -o c:/flutter/engine/.gclient + +# Once the above script finishes successfully, one can make an image of the VM +# for the CI test. +# +# For sanity check, one can also test the VM to make sure that Flutter engine +# can be built in that VM. (The test is optional and our current image is made +# before doing these tests. We only did a reboot before making that image to +# ensure environment variables are loaded. However, Cirrus CI seems to have +# problems reading those environment variables so we ended up setting them in +# ".cirrus.yml" manually.) +# +# To test, first reboot of the terminal (or VM) to ensure that environment +# variables "path", "DEPOT_TOOLS_WIN_TOOLCHAIN", and "GYP_MSVS_OVERRIDE_PATH" +# are set. (Those environment variables are not needed for Cirrus CI as Cirrus +# sets those environment variables by itself.) +# +# After all the environment variables above are loaded correctly, one may test +# build the engine by: +# cd c:/flutter/engine +# gclient sync +# cd src +# python flutter/tools/gn +# ninja -C out/host_debug diff --git a/ci/format.sh b/ci/format.sh index de00b6d3a67b7..e3c8533afd55c 100755 --- a/ci/format.sh +++ b/ci/format.sh @@ -57,7 +57,7 @@ done if [[ $FAILED_CHECKS -ne 0 ]]; then echo "" - echo "ERROR: Some files are formatted incorrectly. To fix, apply diffs above via patch -p0." + echo "ERROR: Some files are formatted incorrectly. To fix, run \`./ci/format.sh | patch -p0\` from the flutter/engine/src/flutter directory." exit 1 fi @@ -73,3 +73,6 @@ if [[ ! -z "$TRAILING_SPACES" ]]; then echo "ERROR: Some files have trailing spaces. To fix, try something like \`find . -name "*.dart" -exec sed -i -e 's/\s\+$//' {} \;\`." exit 1 fi + +# Check GN format consistency +./ci/check_gn_format.py --dry-run true --root-directory . --gn-binary "../buildtools/$OS/gn" diff --git a/ci/licenses.sh b/ci/licenses.sh index a8452f36edcc5..9b7e9896688bb 100755 --- a/ci/licenses.sh +++ b/ci/licenses.sh @@ -3,6 +3,10 @@ set -e shopt -s nullglob echo "Verifying license script is still happy..." +echo "Using pub from `which pub`, dart from `which dart`" + +dart --version + (cd flutter/tools/licenses; pub get; dart --enable-asserts lib/main.dart --src ../../.. --out ../../../out/license_script_output --golden ../../ci/licenses_golden) for f in out/license_script_output/licenses_*; do @@ -42,7 +46,7 @@ fi echo "Checking license count in licenses_flutter..." actualLicenseCount=`tail -n 1 flutter/ci/licenses_golden/licenses_flutter | tr -dc '0-9'` -expectedLicenseCount=2 # When changing this number: Update the error message below as well describing all expected license types. +expectedLicenseCount=3 # When changing this number: Update the error message below as well describing all expected license types. if [ "$actualLicenseCount" -ne "$expectedLicenseCount" ] then @@ -53,6 +57,8 @@ then echo "double-check that all newly added files have a BSD-style license" echo "header with the following copyright:" echo " Copyright 2013 The Flutter Authors. All rights reserved." + echo "Files in 'third_party/bsdiff' may have the following copyright instead:" + echo " Copyright 2003-2005 Colin Percival. All rights reserved." echo "Files in 'third_party/txt' may have an Apache license header instead." echo "If you're absolutely sure that the change in license count is" echo "intentional, update 'flutter/ci/licenses.sh' with the new count." diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 4df1c866548c1..71d65855d3837 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -4,6 +4,37 @@ UNUSED LICENSES: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USED LICENSES: +==================================================================================================== +LIBRARY: bsdiff +ORIGIN: ../../../flutter/third_party/bsdiff/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../flutter/third_party/bsdiff/io/flutter/util/BSDiff.java +---------------------------------------------------------------------------------------------------- +Copyright 2003-2005 Colin Percival. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. 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. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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: engine LIBRARY: txt @@ -19,6 +50,7 @@ FILE: ../../../flutter/assets/zip_asset_store.cc FILE: ../../../flutter/assets/zip_asset_store.h FILE: ../../../flutter/benchmarking/benchmarking.cc FILE: ../../../flutter/benchmarking/benchmarking.h +FILE: ../../../flutter/common/exported_symbols.sym FILE: ../../../flutter/common/settings.cc FILE: ../../../flutter/common/settings.h FILE: ../../../flutter/common/task_runners.cc @@ -55,8 +87,10 @@ FILE: ../../../flutter/flow/layers/opacity_layer.cc FILE: ../../../flutter/flow/layers/opacity_layer.h FILE: ../../../flutter/flow/layers/performance_overlay_layer.cc FILE: ../../../flutter/flow/layers/performance_overlay_layer.h +FILE: ../../../flutter/flow/layers/performance_overlay_layer_unittests.cc FILE: ../../../flutter/flow/layers/physical_shape_layer.cc FILE: ../../../flutter/flow/layers/physical_shape_layer.h +FILE: ../../../flutter/flow/layers/physical_shape_layer_unittests.cc FILE: ../../../flutter/flow/layers/picture_layer.cc FILE: ../../../flutter/flow/layers/picture_layer.h FILE: ../../../flutter/flow/layers/platform_view_layer.cc @@ -83,8 +117,9 @@ FILE: ../../../flutter/flow/skia_gpu_object.cc FILE: ../../../flutter/flow/skia_gpu_object.h FILE: ../../../flutter/flow/texture.cc FILE: ../../../flutter/flow/texture.h +FILE: ../../../flutter/flow/view_holder.cc +FILE: ../../../flutter/flow/view_holder.h FILE: ../../../flutter/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart -FILE: ../../../flutter/fml/arraysize.h FILE: ../../../flutter/fml/base32.cc FILE: ../../../flutter/fml/base32.h FILE: ../../../flutter/fml/base32_unittest.cc @@ -94,8 +129,9 @@ FILE: ../../../flutter/fml/command_line.cc FILE: ../../../flutter/fml/command_line.h FILE: ../../../flutter/fml/command_line_unittest.cc FILE: ../../../flutter/fml/compiler_specific.h +FILE: ../../../flutter/fml/concurrent_message_loop.cc +FILE: ../../../flutter/fml/concurrent_message_loop.h FILE: ../../../flutter/fml/eintr_wrapper.h -FILE: ../../../flutter/fml/export.h FILE: ../../../flutter/fml/file.cc FILE: ../../../flutter/fml/file.h FILE: ../../../flutter/fml/file_unittest.cc @@ -154,6 +190,9 @@ FILE: ../../../flutter/fml/platform/darwin/scoped_block.h FILE: ../../../flutter/fml/platform/darwin/scoped_block.mm FILE: ../../../flutter/fml/platform/darwin/scoped_nsobject.h FILE: ../../../flutter/fml/platform/darwin/scoped_nsobject.mm +FILE: ../../../flutter/fml/platform/darwin/string_range_sanitization.h +FILE: ../../../flutter/fml/platform/darwin/string_range_sanitization.mm +FILE: ../../../flutter/fml/platform/darwin/string_range_sanitization_unittests.mm FILE: ../../../flutter/fml/platform/fuchsia/paths_fuchsia.cc FILE: ../../../flutter/fml/platform/linux/message_loop_linux.cc FILE: ../../../flutter/fml/platform/linux/message_loop_linux.h @@ -175,6 +214,7 @@ FILE: ../../../flutter/fml/platform/win/message_loop_win.h FILE: ../../../flutter/fml/platform/win/native_library_win.cc FILE: ../../../flutter/fml/platform/win/paths_win.cc FILE: ../../../flutter/fml/platform/win/wstring_conversion.h +FILE: ../../../flutter/fml/size.h FILE: ../../../flutter/fml/string_view.cc FILE: ../../../flutter/fml/string_view.h FILE: ../../../flutter/fml/string_view_unittest.cc @@ -182,13 +222,14 @@ FILE: ../../../flutter/fml/synchronization/atomic_object.h FILE: ../../../flutter/fml/synchronization/count_down_latch.cc FILE: ../../../flutter/fml/synchronization/count_down_latch.h FILE: ../../../flutter/fml/synchronization/count_down_latch_unittests.cc +FILE: ../../../flutter/fml/synchronization/semaphore.cc +FILE: ../../../flutter/fml/synchronization/semaphore.h +FILE: ../../../flutter/fml/synchronization/semaphore_unittest.cc FILE: ../../../flutter/fml/synchronization/shared_mutex.h FILE: ../../../flutter/fml/synchronization/shared_mutex_std.cc FILE: ../../../flutter/fml/synchronization/shared_mutex_std.h FILE: ../../../flutter/fml/synchronization/thread_annotations.h FILE: ../../../flutter/fml/synchronization/thread_annotations_unittest.cc -FILE: ../../../flutter/fml/synchronization/thread_checker.h -FILE: ../../../flutter/fml/synchronization/thread_checker_unittest.cc FILE: ../../../flutter/fml/synchronization/waitable_event.cc FILE: ../../../flutter/fml/synchronization/waitable_event.h FILE: ../../../flutter/fml/synchronization/waitable_event_unittest.cc @@ -215,6 +256,70 @@ FILE: ../../../flutter/lib/io/dart_io.cc FILE: ../../../flutter/lib/io/dart_io.h FILE: ../../../flutter/lib/snapshot/libraries.json FILE: ../../../flutter/lib/snapshot/snapshot.h +FILE: ../../../flutter/lib/stub_ui/lib/src/engine.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/alarm_clock.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/assets.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/bitmap_canvas.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/browser_detection.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/engine_delegate.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/layer.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/layer_scene_builder.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/layer_tree.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/platform_message.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/raster_cache.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/rasterizer.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/runtime_delegate.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/surface.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/compositor/viewport_metrics.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/conic.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/dom_canvas.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/dom_renderer.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/engine_canvas.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/history.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/houdini_canvas.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/html_image_codec.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/keyboard.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/onscreen_logging.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/path_to_svg.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/pointer_binding.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/recording_canvas.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/checkable.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/incrementable.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/label_and_value.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/scrollable.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/semantics.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/tappable.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/semantics/text_field.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/services/message_codec.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/services/message_codecs.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/shadow.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/font_collection.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/measurement.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/ruler.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/unicode_range.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/word_break_properties.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text/word_breaker.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/text_editing.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/util.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/validators.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/engine/vector_math.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/browser_location.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/canvas.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/compositing.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/debug_canvas_reuse_overlay.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/geometry.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/hash_codes.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/initialization.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/lerp.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/natives.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/painting.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/pointer.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/semantics.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/text.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/tile_mode.dart +FILE: ../../../flutter/lib/stub_ui/lib/src/ui/window.dart +FILE: ../../../flutter/lib/stub_ui/lib/ui.dart +FILE: ../../../flutter/lib/stub_ui/tool/unicode_sync_script.dart FILE: ../../../flutter/lib/ui/compositing.dart FILE: ../../../flutter/lib/ui/compositing/scene.cc FILE: ../../../flutter/lib/ui/compositing/scene.h @@ -325,23 +430,28 @@ FILE: ../../../flutter/lib/ui/window/window.h FILE: ../../../flutter/runtime/dart_isolate.cc FILE: ../../../flutter/runtime/dart_isolate.h FILE: ../../../flutter/runtime/dart_isolate_unittests.cc +FILE: ../../../flutter/runtime/dart_lifecycle_unittests.cc FILE: ../../../flutter/runtime/dart_service_isolate.cc FILE: ../../../flutter/runtime/dart_service_isolate.h FILE: ../../../flutter/runtime/dart_service_isolate_unittests.cc FILE: ../../../flutter/runtime/dart_snapshot.cc FILE: ../../../flutter/runtime/dart_snapshot.h -FILE: ../../../flutter/runtime/dart_snapshot_buffer.cc -FILE: ../../../flutter/runtime/dart_snapshot_buffer.h FILE: ../../../flutter/runtime/dart_vm.cc FILE: ../../../flutter/runtime/dart_vm.h +FILE: ../../../flutter/runtime/dart_vm_data.cc +FILE: ../../../flutter/runtime/dart_vm_data.h +FILE: ../../../flutter/runtime/dart_vm_lifecycle.cc +FILE: ../../../flutter/runtime/dart_vm_lifecycle.h FILE: ../../../flutter/runtime/dart_vm_unittests.cc FILE: ../../../flutter/runtime/embedder_resources.cc FILE: ../../../flutter/runtime/embedder_resources.h -FILE: ../../../flutter/runtime/fixtures/simple_main.dart +FILE: ../../../flutter/runtime/fixtures/runtime_test.dart FILE: ../../../flutter/runtime/runtime_controller.cc FILE: ../../../flutter/runtime/runtime_controller.h FILE: ../../../flutter/runtime/runtime_delegate.cc FILE: ../../../flutter/runtime/runtime_delegate.h +FILE: ../../../flutter/runtime/runtime_test.cc +FILE: ../../../flutter/runtime/runtime_test.h FILE: ../../../flutter/runtime/service_protocol.cc FILE: ../../../flutter/runtime/service_protocol.h FILE: ../../../flutter/runtime/start_up.cc @@ -352,12 +462,13 @@ FILE: ../../../flutter/shell/common/animator.cc FILE: ../../../flutter/shell/common/animator.h FILE: ../../../flutter/shell/common/engine.cc FILE: ../../../flutter/shell/common/engine.h -FILE: ../../../flutter/shell/common/io_manager.cc -FILE: ../../../flutter/shell/common/io_manager.h +FILE: ../../../flutter/shell/common/fixtures/shell_test.dart FILE: ../../../flutter/shell/common/isolate_configuration.cc FILE: ../../../flutter/shell/common/isolate_configuration.h FILE: ../../../flutter/shell/common/persistent_cache.cc FILE: ../../../flutter/shell/common/persistent_cache.h +FILE: ../../../flutter/shell/common/pipeline.cc +FILE: ../../../flutter/shell/common/pipeline.h FILE: ../../../flutter/shell/common/platform_view.cc FILE: ../../../flutter/shell/common/platform_view.h FILE: ../../../flutter/shell/common/rasterizer.cc @@ -367,6 +478,10 @@ FILE: ../../../flutter/shell/common/run_configuration.h FILE: ../../../flutter/shell/common/shell.cc FILE: ../../../flutter/shell/common/shell.h FILE: ../../../flutter/shell/common/shell_benchmarks.cc +FILE: ../../../flutter/shell/common/shell_io_manager.cc +FILE: ../../../flutter/shell/common/shell_io_manager.h +FILE: ../../../flutter/shell/common/shell_test.cc +FILE: ../../../flutter/shell/common/shell_test.h FILE: ../../../flutter/shell/common/shell_unittests.cc FILE: ../../../flutter/shell/common/skia_event_tracer_impl.cc FILE: ../../../flutter/shell/common/skia_event_tracer_impl.h @@ -382,6 +497,10 @@ FILE: ../../../flutter/shell/common/vsync_waiter_fallback.cc FILE: ../../../flutter/shell/common/vsync_waiter_fallback.h FILE: ../../../flutter/shell/gpu/gpu_surface_gl.cc FILE: ../../../flutter/shell/gpu/gpu_surface_gl.h +FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.cc +FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.h +FILE: ../../../flutter/shell/gpu/gpu_surface_metal.h +FILE: ../../../flutter/shell/gpu/gpu_surface_metal.mm FILE: ../../../flutter/shell/gpu/gpu_surface_software.cc FILE: ../../../flutter/shell/gpu/gpu_surface_software.h FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan.cc @@ -416,11 +535,45 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/app/FlutterActivityEven FILE: ../../../flutter/shell/platform/android/io/flutter/app/FlutterApplication.java FILE: ../../../flutter/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java FILE: ../../../flutter/shell/platform/android/io/flutter/app/FlutterPluginRegistry.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/AndroidKeyProcessor.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/AndroidTouchProcessor.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterSurfaceView.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterTextureView.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEnginePluginRegistry.java FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/FlutterShellArgs.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/dart/PlatformMessageHandler.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/FlutterPlugin.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/PluginRegistry.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityAware.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityControlSurface.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/activity/ActivityPluginBinding.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/broadcastreceiver/BroadcastReceiverAware.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/broadcastreceiver/BroadcastReceiverControlSurface.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/broadcastreceiver/BroadcastReceiverPluginBinding.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/contentprovider/ContentProviderAware.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/contentprovider/ContentProviderControlSurface.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/contentprovider/ContentProviderPluginBinding.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/service/ServiceAware.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/service/ServiceControlSurface.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/plugins/service/ServicePluginBinding.java FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/renderer/OnFirstFrameRenderedListener.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/AccessibilityChannel.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/KeyEventChannel.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/LifecycleChannel.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/LocalizationChannel.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/NavigationChannel.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformChannel.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/SettingsChannel.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/SystemChannel.java +FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/ActivityLifecycleListener.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/BasicMessageChannel.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/BinaryCodec.java @@ -441,11 +594,13 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StandardM FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StringCodec.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java +FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/AccessibilityEventsDelegate.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformView.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewFactory.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewRegistry.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewRegistryImpl.java +FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsAccessibilityDelegate.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java @@ -453,6 +608,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/util/PathUtils.java FILE: ../../../flutter/shell/platform/android/io/flutter/util/Preconditions.java FILE: ../../../flutter/shell/platform/android/io/flutter/util/Predicate.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java +FILE: ../../../flutter/shell/platform/android/io/flutter/view/AccessibilityViewEmbedder.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterCallbackInformation.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterMain.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -461,7 +617,6 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterView.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/ResourceCleaner.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/ResourceExtractor.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/ResourcePaths.java -FILE: ../../../flutter/shell/platform/android/io/flutter/view/ResourceUpdater.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/TextureRegistry.java FILE: ../../../flutter/shell/platform/android/io/flutter/view/VsyncWaiter.java FILE: ../../../flutter/shell/platform/android/library_loader.cc @@ -473,6 +628,40 @@ FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.cc FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.h FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.cc FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/byte_stream_wrappers.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/encodable_value_unittests.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/engine_method_result.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/basic_message_channel.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/binary_messenger.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/encodable_value.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/engine_method_result.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/json_message_codec.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/json_method_codec.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/json_type.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/message_codec.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_call.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_channel.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_codec.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_result.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_message_codec.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_method_codec.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/json_message_codec.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/json_method_codec.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_call_unittests.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/plugin_registrar_unittests.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/standard_codec.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/standard_codec_serializer.h +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/standard_message_codec_unittests.cc +FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc +FILE: ../../../flutter/shell/platform/common/cpp/incoming_message_dispatcher.cc +FILE: ../../../flutter/shell/platform/common/cpp/incoming_message_dispatcher.h +FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_export.h +FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_messenger.h +FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_plugin_registrar.h +FILE: ../../../flutter/shell/platform/common/cpp/text_input_model.cc +FILE: ../../../flutter/shell/platform/common/cpp/text_input_model.h FILE: ../../../flutter/shell/platform/darwin/common/buffer_conversions.h FILE: ../../../flutter/shell/platform/darwin/common/buffer_conversions.mm FILE: ../../../flutter/shell/platform/darwin/common/command_line.h @@ -548,10 +737,28 @@ FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_gl.mm +FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal.h +FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_metal.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_software.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_surface_software.mm FILE: ../../../flutter/shell/platform/darwin/ios/platform_view_ios.h FILE: ../../../flutter/shell/platform/darwin/ios/platform_view_ios.mm +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FLEOpenGLContextHandling.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FLEPlugin.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FLEPluginRegistrar.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FLEReshapeListener.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FLEView.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FLEViewController.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterMacOS.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Info.plist +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FLETextInputModel.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FLETextInputModel.mm +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FLETextInputPlugin.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FLETextInputPlugin.mm +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FLEView.mm +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FLEViewController.mm +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FLEViewController_Internal.h +FILE: ../../../flutter/shell/platform/darwin/macos/framework/module.modulemap FILE: ../../../flutter/shell/platform/embedder/assets/EmbedderInfo.plist FILE: ../../../flutter/shell/platform/embedder/assets/embedder.modulemap FILE: ../../../flutter/shell/platform/embedder/embedder.cc @@ -561,29 +768,177 @@ FILE: ../../../flutter/shell/platform/embedder/embedder_engine.h FILE: ../../../flutter/shell/platform/embedder/embedder_external_texture_gl.cc FILE: ../../../flutter/shell/platform/embedder/embedder_external_texture_gl.h FILE: ../../../flutter/shell/platform/embedder/embedder_include.c +FILE: ../../../flutter/shell/platform/embedder/embedder_safe_access.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface.cc FILE: ../../../flutter/shell/platform/embedder/embedder_surface.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface_gl.cc FILE: ../../../flutter/shell/platform/embedder/embedder_surface_gl.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface_software.cc FILE: ../../../flutter/shell/platform/embedder/embedder_surface_software.h -FILE: ../../../flutter/shell/platform/embedder/fixtures/simple_main.dart +FILE: ../../../flutter/shell/platform/embedder/embedder_task_runner.cc +FILE: ../../../flutter/shell/platform/embedder/embedder_task_runner.h +FILE: ../../../flutter/shell/platform/embedder/embedder_thread_host.cc +FILE: ../../../flutter/shell/platform/embedder/embedder_thread_host.h +FILE: ../../../flutter/shell/platform/embedder/fixtures/main.dart FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.cc FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.h +FILE: ../../../flutter/shell/platform/embedder/vsync_waiter_embedder.cc +FILE: ../../../flutter/shell/platform/embedder/vsync_waiter_embedder.h +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/fuchsia/lib/fuchsia.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/fuchsia/sdk_ext/fuchsia.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/fuchsia/sdk_ext/fuchsia.h +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/handle.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/handle_waiter.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/src/system.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/lib/zircon.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle.h +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle_waiter.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/handle_waiter.h +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.h +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.h +FILE: ../../../flutter/shell/platform/fuchsia/dart/builtin_libraries.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart/builtin_libraries.h +FILE: ../../../flutter/shell/platform/fuchsia/dart/dart_component_controller.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart/dart_component_controller.h +FILE: ../../../flutter/shell/platform/fuchsia/dart/dart_runner.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart/dart_runner.h +FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/builtin.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/script_runner_snapshot.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/shim.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/snapshot.cc.tmpl +FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/snapshot.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/embedder/snapshot.h +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/goodbye_dart/goodbye_dart.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/goodbye_dart/goodbye_dart_test +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/goodbye_dart/meta/goodbye_dart_aot.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/goodbye_dart/meta/goodbye_dart_jit.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/greeting/greeting.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_app_dart/interfaces/hello.fidl +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_app_dart/main.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_app_dart/meta/hello_app_dart_aot.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_app_dart/meta/hello_app_dart_jit.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/bin/hello_dart.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_aot.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_aot_product.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_debug.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_jit.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/examples/hello_dart/meta/hello_dart_jit_product.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/integration/main.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/integration/meta/dart_aot_runner_test.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/integration/meta/dart_jit_runner_test.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/kernel/libraries.json +FILE: ../../../flutter/shell/platform/fuchsia/dart/logging.h +FILE: ../../../flutter/shell/platform/fuchsia/dart/main.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart/mapped_resource.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart/mapped_resource.h +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/aot_product_runtime +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/aot_runtime +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_aot_product_runner.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_aot_runner.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_jit_product_runner.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_jit_runner.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/dart_zircon_test.cmx +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/jit_product_runtime +FILE: ../../../flutter/shell/platform/fuchsia/dart/meta/jit_runtime +FILE: ../../../flutter/shell/platform/fuchsia/dart/service_isolate.cc +FILE: ../../../flutter/shell/platform/fuchsia/dart/service_isolate.h +FILE: ../../../flutter/shell/platform/fuchsia/dart/vmservice/empty.dart +FILE: ../../../flutter/shell/platform/fuchsia/dart/vmservice/meta/vmservice.cmx +FILE: ../../../flutter/shell/platform/fuchsia/flutter/collect_traces.dart +FILE: ../../../flutter/shell/platform/fuchsia/flutter/component.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/component.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/compositor_context.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/compositor_context.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/context_writer_bridge.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/context_writer_bridge.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/engine.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/engine.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/fuchsia_font_manager.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/fuchsia_font_manager.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/fuchsia_font_manager_unittest.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/isolate_configurator.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/isolate_configurator.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/kernel/extract_far.dart +FILE: ../../../flutter/shell/platform/fuchsia/flutter/kernel/framework_shim.dart +FILE: ../../../flutter/shell/platform/fuchsia/flutter/kernel/libraries.json +FILE: ../../../flutter/shell/platform/fuchsia/flutter/logging.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/loop.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/loop.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/main.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/aot_product_runtime +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/aot_runtime +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_aot_product_runner.cmx +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_jit_product_runner.cmx +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_jit_runner.cmx +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/flutter_runner_tests.cmx +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/jit_product_runtime +FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/jit_runtime +FILE: ../../../flutter/shell/platform/fuchsia/flutter/platform_view.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/platform_view.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner_context.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner_context.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/service_provider_dir.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/service_provider_dir.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/session_connection.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/session_connection.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_observers.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_observers.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_runner_adapter.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_runner_adapter.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/thread.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/thread.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/unique_fdio_ns.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_recorder.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_recorder.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_waiter.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_waiter.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface_pool.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface_pool.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/vulkan_surface_producer.h +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/files.cc +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/files.h +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/handle_exception.cc +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/handle_exception.h +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/inlines.h +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/logging.h +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/tempfs.cc +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/tempfs.h +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/vmo.cc +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/vmo.h +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/vmservice_object.cc +FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/vmservice_object.h +FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_controller.cc +FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_controller_unittests.cc +FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h +FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/flutter_window_controller.h +FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h +FILE: ../../../flutter/shell/platform/glfw/flutter_glfw.cc +FILE: ../../../flutter/shell/platform/glfw/key_event_handler.cc +FILE: ../../../flutter/shell/platform/glfw/key_event_handler.h +FILE: ../../../flutter/shell/platform/glfw/keyboard_hook_handler.h +FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h +FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc +FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h FILE: ../../../flutter/shell/version/version.cc FILE: ../../../flutter/shell/version/version.h FILE: ../../../flutter/sky/packages/flutter_services/lib/empty.dart FILE: ../../../flutter/sky/tools/roll/patches/chromium/android_build.patch -FILE: ../../../flutter/synchronization/pipeline.cc -FILE: ../../../flutter/synchronization/pipeline.h -FILE: ../../../flutter/synchronization/semaphore.cc -FILE: ../../../flutter/synchronization/semaphore.h -FILE: ../../../flutter/synchronization/semaphore_unittest.cc FILE: ../../../flutter/third_party/txt/src/txt/platform.cc FILE: ../../../flutter/third_party/txt/src/txt/platform.h FILE: ../../../flutter/third_party/txt/src/txt/platform_android.cc +FILE: ../../../flutter/third_party/txt/src/txt/platform_linux.cc FILE: ../../../flutter/third_party/txt/src/txt/platform_mac.mm -FILE: ../../../flutter/vulkan/skia_vulkan_header.h FILE: ../../../flutter/vulkan/vulkan_application.cc FILE: ../../../flutter/vulkan/vulkan_application.h FILE: ../../../flutter/vulkan/vulkan_backbuffer.cc @@ -617,6 +972,9 @@ FILE: ../../../flutter/vulkan/vulkan_utilities.cc FILE: ../../../flutter/vulkan/vulkan_utilities.h FILE: ../../../flutter/vulkan/vulkan_window.cc FILE: ../../../flutter/vulkan/vulkan_window.h +FILE: ../../../flutter/web_sdk/flutter_kernel_sdk.dart +FILE: ../../../flutter/web_sdk/libraries.json +FILE: ../../../flutter/web_sdk/sdk_rewriter.dart ---------------------------------------------------------------------------------------------------- Copyright 2013 The Flutter Authors. All rights reserved. @@ -646,9 +1004,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== ==================================================================================================== +LIBRARY: engine LIBRARY: txt ORIGIN: ../../../flutter/third_party/txt/LICENSE TYPE: LicenseType.apache +FILE: ../../../flutter/flow/flow_run_all_unittests.cc +FILE: ../../../flutter/flow/flow_test_utils.cc +FILE: ../../../flutter/flow/flow_test_utils.h FILE: ../../../flutter/third_party/txt/benchmarks/paint_record_benchmarks.cc FILE: ../../../flutter/third_party/txt/benchmarks/paragraph_benchmarks.cc FILE: ../../../flutter/third_party/txt/benchmarks/paragraph_builder_benchmarks.cc @@ -931,4 +1293,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ==================================================================================================== -Total license count: 2 +Total license count: 3 diff --git a/ci/licenses_golden/licenses_fuchsia b/ci/licenses_golden/licenses_fuchsia new file mode 100644 index 0000000000000..027323ad472ba --- /dev/null +++ b/ci/licenses_golden/licenses_fuchsia @@ -0,0 +1,1686 @@ +Signature: f3ae86bf01d57e552b045084f4601d6f + +UNUSED LICENSES: + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +USED LICENSES: + +==================================================================================================== +LIBRARY: fuchsia_sdk +ORIGIN: ../../../LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/service_provider.fidl +---------------------------------------------------------------------------------------------------- +Copyright 2014 The Chromium Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/.build-id/0c/7180f0254d66fecfc84bef3339a7b71c457dcd.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/25/96d83da12ef9224f4df627b37dddb0f871b655.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/2f/341201ed67d5c7171b0a0d606861bd1c531eba.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/47/b16a99629da959039391bd8804d7d22dd27b50.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/59/896073939655951a6a08f9a376b4ae10244616.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/6d/ced323e99bc31a5afa28eca8d3d98ef09d46ef.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/73/1f40fcea15370e.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/7e/3f807cda5a47e60285a751b8265d621551de02.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/82/5b314d45feed623c70bf21bd7c9ceb62fb4d4e.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/83/ccf51a89d5bcf1709510507d66c3f0c291a969.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/90/1b18453902c341c25c57ef2e40c175614a5afe.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/9f/5e21c81427ad236ba27374a6a13f1bffc3e9dd.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/b0/ae926bebfc82c2.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/b0/cb33d5e533ba8f6dcb73cc9c158cb8247f0263.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/ba/5f203efc80a0dd.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/c9/0d4b5704d2b548e8488663b69bf86fdfef59ea.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/ca/acfd23dc9b1a5d8929f6da0e864e07e989353b.debug +FILE: ../../../fuchsia/sdk/linux/.build-id/e5/d60a28793ffcc0.debug +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libVkLayer_core_validation.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libVkLayer_image_pipe_swapchain.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libVkLayer_object_tracker.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libVkLayer_parameter_validation.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libVkLayer_threading.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libVkLayer_unique_objects.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libasync-default.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libfdio.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libmemfs.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libsvc.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libsyslog.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libtrace-engine.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/dist/libvulkan.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/lib/libasync-default.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/lib/libfdio.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/lib/libmemfs.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/lib/libsvc.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/lib/libsync.a +FILE: ../../../fuchsia/sdk/linux/arch/arm64/lib/libsyslog.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/lib/libtrace-engine.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/lib/libvulkan.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/alloca.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/ar.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/arpa/ftp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/arpa/inet.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/arpa/nameser.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/arpa/nameser_compat.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/arpa/telnet.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/arpa/tftp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/assert.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/endian.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/fenv.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/float.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/ipc.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/reg.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/setjmp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/aarch64/stat.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/alltypes.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/endian.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/errno.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/fcntl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/fenv.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/float.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/io.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/ipc.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/limits.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/msg.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/posix.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/reg.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/sem.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/setjmp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/shm.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/socket.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/stat.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/statfs.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/termios.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/endian.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/fenv.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/float.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/io.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/ipc.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/reg.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/setjmp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/x86_64/stat.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/byteswap.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/complex.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/cpio.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/crypt.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/ctype.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/dirent.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/dlfcn.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/elf.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/endian.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/err.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/errno.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/fcntl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/features.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/fenv.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/float.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/fmtmsg.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/fnmatch.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/ftw.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/getopt.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/glob.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/grp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/iconv.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/ifaddrs.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/inttypes.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/iso646.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/langinfo.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/libgen.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/limits.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/link.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/locale.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/malloc.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/math.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/memory.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/monetary.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/net/ethernet.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/net/if.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/net/if_arp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/net/route.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netdb.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/ether.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/icmp6.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/if_ether.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/igmp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/in.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/in_systm.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/ip.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/ip6.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/ip_icmp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/tcp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netinet/udp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/netpacket/packet.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/nl_types.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/paths.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/poll.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/pthread.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/pwd.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/regex.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/resolv.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sched.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/search.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/semaphore.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/setjmp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/spawn.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/stdio.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/stdlib.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/stdnoreturn.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/string.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/strings.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/stropts.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/acct.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/auxv.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/dir.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/errno.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/eventfd.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/fcntl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/file.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/fsuid.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/io.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/ipc.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/klog.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/mman.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/mount.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/msg.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/mtio.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/param.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/personality.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/poll.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/quota.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/random.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/reboot.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/reg.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/select.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/sem.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/shm.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/signalfd.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/socket.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/stat.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/statfs.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/statvfs.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/stropts.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/swap.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/syslog.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/termios.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/time.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/timeb.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/timerfd.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/times.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/timex.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/ttydefaults.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/types.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/ucontext.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/uio.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/un.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/utsname.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/vfs.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sys/wait.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/sysexits.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/syslog.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/tar.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/termios.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/threads.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/time.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/uchar.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/ucontext.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/unistd.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/utime.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/values.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/wait.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/wchar.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/wctype.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/wordexp.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls.banjo +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/definitions.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/lib/Scrt1.o +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/lib/libc.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/lib/libdl.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/lib/libm.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/lib/libpthread.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/lib/librt.so +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/lib/libzircon.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libVkLayer_core_validation.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libVkLayer_image_pipe_swapchain.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libVkLayer_object_tracker.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libVkLayer_parameter_validation.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libVkLayer_threading.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libVkLayer_unique_objects.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libasync-default.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libfdio.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libmemfs.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libsvc.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libsyslog.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libtrace-engine.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/dist/libvulkan.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/lib/libasync-default.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/lib/libfdio.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/lib/libmemfs.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/lib/libsvc.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/lib/libsync.a +FILE: ../../../fuchsia/sdk/linux/arch/x64/lib/libsyslog.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/lib/libtrace-engine.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/lib/libvulkan.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/alloca.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/ar.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/arpa/ftp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/arpa/inet.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/arpa/nameser.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/arpa/nameser_compat.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/arpa/telnet.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/arpa/tftp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/assert.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/endian.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/fenv.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/float.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/ipc.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/reg.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/setjmp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/aarch64/stat.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/alltypes.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/endian.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/errno.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/fcntl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/fenv.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/float.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/io.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/ipc.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/limits.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/msg.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/posix.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/reg.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/sem.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/setjmp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/shm.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/socket.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/stat.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/statfs.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/termios.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/endian.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/fenv.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/float.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/io.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/ipc.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/reg.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/setjmp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/x86_64/stat.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/byteswap.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/complex.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/cpio.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/crypt.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/ctype.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/dirent.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/dlfcn.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/elf.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/endian.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/err.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/errno.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/fcntl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/features.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/fenv.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/float.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/fmtmsg.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/fnmatch.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/ftw.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/getopt.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/glob.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/grp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/iconv.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/ifaddrs.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/inttypes.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/iso646.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/langinfo.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/libgen.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/limits.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/link.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/locale.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/malloc.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/math.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/memory.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/monetary.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/net/ethernet.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/net/if.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/net/if_arp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/net/route.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netdb.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/ether.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/icmp6.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/if_ether.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/igmp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/in.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/in_systm.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/ip.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/ip6.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/ip_icmp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/tcp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netinet/udp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/netpacket/packet.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/nl_types.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/paths.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/poll.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/pthread.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/pwd.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/regex.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/resolv.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sched.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/search.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/semaphore.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/setjmp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/spawn.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/stdio.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/stdlib.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/stdnoreturn.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/string.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/strings.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/stropts.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/acct.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/auxv.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/dir.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/errno.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/eventfd.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/fcntl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/file.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/fsuid.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/io.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/ipc.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/klog.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/mman.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/mount.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/msg.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/mtio.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/param.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/personality.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/poll.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/quota.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/random.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/reboot.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/reg.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/select.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/sem.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/shm.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/signal.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/signalfd.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/socket.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/stat.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/statfs.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/statvfs.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/stropts.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/swap.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/syslog.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/termios.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/time.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/timeb.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/timerfd.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/times.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/timex.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/ttydefaults.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/types.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/ucontext.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/uio.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/un.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/utsname.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/vfs.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sys/wait.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/sysexits.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/syslog.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/tar.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/termios.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/threads.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/time.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/uchar.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/ucontext.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/unistd.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/utime.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/values.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/wait.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/wchar.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/wctype.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/wordexp.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls.banjo +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/definitions.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/lib/Scrt1.o +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/lib/libc.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/lib/libdl.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/lib/libm.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/lib/libpthread.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/lib/librt.so +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/lib/libzircon.so +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/composition_delegate.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/composition_delegate/composition_delegate.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/internal/layout_logic/_layout_logic.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/internal/layout_logic/_layout_strategy.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/internal/layout_logic/split_evenly_strategy/split_evenly_strategy.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/internal/layout_logic/stack_strategy/stack_strategy.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/internal/tree/_surface_node.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/internal/tree/_surface_tree.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/layout/layout_types.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/surface/surface_relation.dart +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/bits.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/xunion.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_logger/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_media/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/internal/_ongoing_activity_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/internal/_streaming_intent_handler_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/ongoing_activity.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/streaming_intent_handler.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic/lib/src/view_token_pair.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic/lib/views.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic_flutter/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_services/lib/src/incoming.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_services/lib/src/outgoing.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_services/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/lib/src/internal/_flags.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/lib/src/vmo_file.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/meta.json +FILE: ../../../fuchsia/sdk/linux/dart/zircon/meta.json +FILE: ../../../fuchsia/sdk/linux/docs/low_level.json +FILE: ../../../fuchsia/sdk/linux/docs/metadata_schemas.json +FILE: ../../../fuchsia/sdk/linux/docs/open_source.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.auth.oldtokens/credentials_producer.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.auth.oldtokens/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.auth/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth.gatt/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth.le/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.camera/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.castauth/cast_auth.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.castauth/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.castsetup/cast_setup.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.castsetup/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.castsysteminfo/cast_system_info.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.castsysteminfo/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.cobalt/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.crash/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.developer.tiles/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.feedback/data_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.feedback/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.fonts/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.ethernet/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.images/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.intl/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.intl/property_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.io/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ldsvc/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ledger/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.logger/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.math/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.audio/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.drm/content_decryption.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.drm/license_session.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.drm/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.playback/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.sessions/image.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.sessions/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/audio_core.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.mediacodec/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.mem/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular.auth/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/component/message_queue.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_shell_factory.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.http/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.mdns/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.oldhttp/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net/namelookup.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.netstack/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.process/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.simplecamera/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.speech/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/types.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysinfo/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.app/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.app/view.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.app/view_config.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/tokens.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/keys.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/modifiers.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.policy/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.scenic/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.vectorial/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.views/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.views/view.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.views/view_config.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.views/view_token.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1token/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.web/context.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.web/frame.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.web/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.web/navigation.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.wlan.common/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.wlan.service/meta.json +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.wlan.stats/meta.json +FILE: ../../../fuchsia/sdk/linux/images/fuchsia.zbi-meta.json +FILE: ../../../fuchsia/sdk/linux/images/fvm.blk-meta.json +FILE: ../../../fuchsia/sdk/linux/images/fvm.sparse.blk-meta.json +FILE: ../../../fuchsia/sdk/linux/images/local.esp.blk-meta.json +FILE: ../../../fuchsia/sdk/linux/images/qemu-kernel.bin-meta.json +FILE: ../../../fuchsia/sdk/linux/images/zircon.vboot-meta.json +FILE: ../../../fuchsia/sdk/linux/meta/manifest.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/cc_prebuilt_library.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/cc_source_library.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/common.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/dart_library.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/documentation.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/fidl_library.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/host_tool.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/image.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/loadable_module.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/manifest.json +FILE: ../../../fuchsia/sdk/linux/meta/schemas/sysroot.json +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/async-default/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/async-loop-cpp/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/async-loop/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/async/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/directory.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/fd.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/fidl-async/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/fidl/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/envelope_frames.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/internal_callable_traits.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/visitor.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/internal.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_sync/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/fit/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/images_cpp/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/memfs/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/include/lib/ui/scenic/cpp/view_token_pair.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/svc/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/sync/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/syslog/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/sysroot/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/trace-engine/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_core_validation.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_image_pipe_swapchain.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_object_tracker.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_parameter_validation.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_standard_validation.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_threading.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan_layers/data/vulkan/explicit_layer.d/VkLayer_unique_objects.json +FILE: ../../../fuchsia/sdk/linux/pkg/vulkan_layers/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/pager.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/meta.json +FILE: ../../../fuchsia/sdk/linux/pkg/zx/pager.cpp +FILE: ../../../fuchsia/sdk/linux/target/arm64/fuchsia.zbi +FILE: ../../../fuchsia/sdk/linux/target/arm64/fvm.blk +FILE: ../../../fuchsia/sdk/linux/target/arm64/fvm.sparse.blk +FILE: ../../../fuchsia/sdk/linux/target/arm64/qemu-kernel.bin +FILE: ../../../fuchsia/sdk/linux/target/x64/fuchsia.zbi +FILE: ../../../fuchsia/sdk/linux/target/x64/fvm.blk +FILE: ../../../fuchsia/sdk/linux/target/x64/fvm.sparse.blk +FILE: ../../../fuchsia/sdk/linux/target/x64/local.esp.blk +FILE: ../../../fuchsia/sdk/linux/target/x64/qemu-kernel.bin +FILE: ../../../fuchsia/sdk/linux/target/x64/zircon.vboot +FILE: ../../../fuchsia/sdk/linux/tools/bootserver +FILE: ../../../fuchsia/sdk/linux/tools/bootserver-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/cmc +FILE: ../../../fuchsia/sdk/linux/tools/cmc-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/dart +FILE: ../../../fuchsia/sdk/linux/tools/dart_kernel_compiler-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/dart_prebuilts/dart_runner/platform_strong.dill +FILE: ../../../fuchsia/sdk/linux/tools/dart_prebuilts/flutter_runner/platform_strong.dill +FILE: ../../../fuchsia/sdk/linux/tools/dart_prebuilts/frontend_server_tool.snapshot +FILE: ../../../fuchsia/sdk/linux/tools/dart_prebuilts/kernel_compiler.snapshot +FILE: ../../../fuchsia/sdk/linux/tools/dev_finder +FILE: ../../../fuchsia/sdk/linux/tools/dev_finder-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/far +FILE: ../../../fuchsia/sdk/linux/tools/far-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/fidl-format +FILE: ../../../fuchsia/sdk/linux/tools/fidl-format-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/fidlc +FILE: ../../../fuchsia/sdk/linux/tools/fidlc-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/fidlgen +FILE: ../../../fuchsia/sdk/linux/tools/fidlgen-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/fidlgen_dart +FILE: ../../../fuchsia/sdk/linux/tools/fidlgen_dart-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/fvm +FILE: ../../../fuchsia/sdk/linux/tools/fvm-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/gen_snapshot-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/gen_snapshot.arm64 +FILE: ../../../fuchsia/sdk/linux/tools/gen_snapshot.x64 +FILE: ../../../fuchsia/sdk/linux/tools/gen_snapshot_product.arm64 +FILE: ../../../fuchsia/sdk/linux/tools/gen_snapshot_product.x64 +FILE: ../../../fuchsia/sdk/linux/tools/loglistener +FILE: ../../../fuchsia/sdk/linux/tools/loglistener-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/merkleroot +FILE: ../../../fuchsia/sdk/linux/tools/merkleroot-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/minfs +FILE: ../../../fuchsia/sdk/linux/tools/minfs-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/pm +FILE: ../../../fuchsia/sdk/linux/tools/pm-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/symbolize +FILE: ../../../fuchsia/sdk/linux/tools/symbolize-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/zbi +FILE: ../../../fuchsia/sdk/linux/tools/zbi-meta.json +FILE: ../../../fuchsia/sdk/linux/tools/zxdb +FILE: ../../../fuchsia/sdk/linux/tools/zxdb-meta.json +---------------------------------------------------------------------------------------------------- +Copyright 2019 The Fuchsia Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/null.h +TYPE: LicenseType.mit +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/bits/null.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/multiboot.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/time.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/bits/null.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/boot/multiboot.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/time.h +---------------------------------------------------------------------------------------------------- +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +==================================================================================================== + +==================================================================================================== +LIBRARY: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/driver-config.h + ../../../fuchsia/sdk/linux/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/driver-config.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/image.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/sysconfig.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/dlfcn.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/features.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/pci.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/usb/dfu.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/limits.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/smc.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/threads.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/boot/driver-config.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/boot/image.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/boot/sysconfig.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/dlfcn.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/features.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/pci.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/usb/dfu.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/limits.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/smc.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/threads.h +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/codec.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/enum.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/error.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/hash_codes.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/interface_async.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/message.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/struct.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/table.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/types.dart +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/union.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia/lib/src/fakes/fuchsia_fakes.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_logger/lib/logger.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_logger/lib/src/internal/_fuchsia_log_writer.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_logger/lib/src/internal/_log_message.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_logger/lib/src/internal/_log_writer.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_logger/lib/src/internal/_stdout_log_writer.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_logger/lib/src/logger/logger.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_media/lib/media.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_media/lib/src/media.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/agent.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/codecs.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/entity.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/lifecycle.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/logger.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/module.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/proposal.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/service_connection.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/agent/agent.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/agent/agent_task_handler.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/agent/internal/_agent_context.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/agent/internal/_agent_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/entity/entity.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/entity/entity_exceptions.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/entity/internal/_entity_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/internal/_component_context.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/lifecycle/internal/_lifecycle_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/lifecycle/lifecycle.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/embedded_module.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/intent.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/intent_handler.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/internal/_fidl_transformers.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/internal/_intent_handler_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/internal/_module_context.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/internal/_module_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/module.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/module_state_exception.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/module/noop_intent_handler.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/proposal/internal/_proposal_listener_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/proposal/proposal.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_modular/lib/src/service_connection/agent_service_connection.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic_flutter/lib/src/child_view.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic_flutter/lib/src/child_view_connection.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_services/lib/services.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_services/lib/src/service_provider_impl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/lib/src/internal/_error_node.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/lib/src/pseudo_dir.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/lib/src/pseudo_file.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/lib/src/service.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/lib/src/vnode.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_vfs/lib/vfs.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/channel.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/channel_reader.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/constants.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/errors.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/eventpair.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/fakes/handle.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/fakes/handle_waiter.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/fakes/system.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/handle_wrapper.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/socket.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/socket_reader.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/vmo.dart +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.auth/attestation_signer.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.auth/common.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth.gatt/types.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth.le/central.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth/nullables.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.camera/camera.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.camera/manager.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.cobalt/cobalt.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.crash/analyzer.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.developer.tiles/tiles.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.hardware.ethernet/ethernet.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.images/encoded_image.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.images/image_info.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.images/image_pipe.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.images/memory_type.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.intl/intl.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.io/io.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ldsvc/ldsvc.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.logger/logger.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.audio/gain_control.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.playback/player.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.playback/source_manager.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.sessions/playback_capabilities.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.sessions/playback_status.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.sessions/service.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.sessions/session.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/audio_device_enumerator.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/audio_renderer.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/metadata.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/stream.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/stream_common.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/stream_processor.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/stream_type.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/timeline_function.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.mediacodec/codec_factory.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/intent/intent_handler.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/module/module_manifest.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/puppet_master.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_command.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_options.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_visibility_state.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.http/client.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net/connectivity.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net/net.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net/socket.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.process/launcher.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.process/resolver.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.simplecamera/simple_camera.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/job_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysinfo/sysinfo.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/allocator.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/collection.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/constraints.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/driver_connector.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/format_modifier.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.app/view_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/pose_buffer_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/commands.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.policy/display_usage.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.scenic/commands.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.scenic/events.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.scenic/scenic.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.scenic/session.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.vectorial/commands.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.vectorial/events.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.views/commands.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.views/events.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/view_snapshot.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.wlan.common/wlan_common.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.wlan.stats/wlan_stats.fidl +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/exception.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/include/lib/async/cpp/exception.h +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/include/lib/async/cpp/time.h +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/include/lib/async/cpp/trap.h +FILE: ../../../fuchsia/sdk/linux/pkg/async/include/lib/async/exception.h +FILE: ../../../fuchsia/sdk/linux/pkg/async/include/lib/async/time.h +FILE: ../../../fuchsia/sdk/linux/pkg/async/include/lib/async/trap.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/spawn.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl-async/bind.c +FILE: ../../../fuchsia/sdk/linux/pkg/fidl-async/include/lib/fidl-async/bind.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl/epitaph.c +FILE: ../../../fuchsia/sdk/linux/pkg/fidl/handle_closing.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl/include/lib/fidl/epitaph.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl/include/lib/fidl/transport.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl/transport.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/builder.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/cpp/builder.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/cpp/message.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/cpp/message_buffer.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/cpp/message_builder.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/cpp/message_part.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/walker.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/linearizing.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/message.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/message_buffer.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/message_builder.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/walker.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/binding.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/binding_set.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/enum.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/interface_ptr_set.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/header.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/implementation.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_handler.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/message_reader.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/pending_response.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/proxy_controller.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/stub_controller.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/internal/weak_stub_controller.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/optional.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/thread_safe_binding_set.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/include/lib/fidl/cpp/type_converter.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/internal/message_handler.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/internal/message_reader.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/internal/pending_response.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/internal/proxy.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/internal/proxy_controller.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/internal/stub.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/internal/stub_controller.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp/internal/weak_stub_controller.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/clone.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/decoder.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/encoder.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/clone.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/coding_traits.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/comparison.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/decoder.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/encoder.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/internal/logging.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/object_coding.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/string.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/traits.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/include/lib/fidl/cpp/vector.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/internal/logging.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_base/string.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_handle.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_sync/include/lib/fidl/cpp/interface_request.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_sync/include/lib/fidl/cpp/internal/synchronous_proxy.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_sync/include/lib/fidl/cpp/synchronous_interface_ptr.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_cpp_sync/internal/synchronous_proxy.cc +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/bridge.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/bridge_internal.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/defer.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/function_traits.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/nullable.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/optional.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/promise.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/promise_internal.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/result.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/scheduler.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/scope.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/sequencer.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/single_threaded_executor.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/thread_safety.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/traits.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/variant.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/promise.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fit/scheduler.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fit/scope.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fit/sequencer.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fit/single_threaded_executor.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/images_cpp/images.cc +FILE: ../../../fuchsia/sdk/linux/pkg/images_cpp/include/lib/images/cpp/images.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/include/lib/ui/scenic/cpp/id.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/include/lib/ui/scenic/cpp/util/mesh_utils.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/util/mesh_utils.cc +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/view_token_pair.cc +FILE: ../../../fuchsia/sdk/linux/pkg/svc/include/lib/svc/dir.h +FILE: ../../../fuchsia/sdk/linux/pkg/sync/include/lib/sync/condition.h +FILE: ../../../fuchsia/sdk/linux/pkg/sync/include/lib/sync/internal/condition-template.h +FILE: ../../../fuchsia/sdk/linux/pkg/sync/include/lib/sync/mutex.h +FILE: ../../../fuchsia/sdk/linux/pkg/syslog/include/lib/syslog/global.h +FILE: ../../../fuchsia/sdk/linux/pkg/syslog/include/lib/syslog/logger.h +FILE: ../../../fuchsia/sdk/linux/pkg/syslog/include/lib/syslog/wire_format.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/bti.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/debuglog.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/guest.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/bti.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/debuglog.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/guest.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/interrupt.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/iommu.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/pmt.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/profile.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/resource.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/suspend_token.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/vcpu.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/interrupt.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/iommu.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/profile.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/resource.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/vcpu.cpp +---------------------------------------------------------------------------------------------------- +Copyright 2018 The Fuchsia Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/e820.h + ../../../fuchsia/sdk/linux/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/e820.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/device/audio.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/fidl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/gpt.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/usb/cdc.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/usb/video.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/process.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/rights.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/sanitizer.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/hypervisor.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/iommu.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/policy.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/system.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/tls.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/boot/e820.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/device/audio.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/fidl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/gpt.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/usb/cdc.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/usb/video.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/process.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/rights.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/sanitizer.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/hypervisor.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/iommu.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/policy.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/system.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/tls.h +FILE: ../../../fuchsia/sdk/linux/dart/composition_delegate/lib/src/surface/surface.dart +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.auth/auth_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.auth/auth_provider_factory.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.auth/token_manager.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth.gatt/client.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth.gatt/server.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth.le/peripheral.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth.le/types.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.bluetooth/status.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.cobalt/cobalt_controller.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.images/presentation_info.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/audio_capturer.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.mem/buffer.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular.auth/account/account.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular.auth/account_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/agent/agent.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/agent/agent_context.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/agent/agent_controller/agent_controller.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/agent/agent_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/clipboard/clipboard.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/component/component_context.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/config/config.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/context/context_engine.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/context/debug.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/context/metadata.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/entity/entity.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/entity/entity_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/entity/entity_reference_factory.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/entity/entity_resolver.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/intent/intent.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/lifecycle/lifecycle.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/module/link_path.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/module/module_data.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/module/module_state.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/module_resolver/module_resolver.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/session/device_map.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/create_link.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/create_module_parameter_map.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_shell.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_state.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/suggestion/debug.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/surface/container.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/surface/surface.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/user_intelligence/intelligence_services.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/user_intelligence/scope.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/user_intelligence/user_intelligence_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.mdns/mdns.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.speech/speech_to_text.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/flat_namespace.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/commands.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/display_info.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/events.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/hit.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/nodes.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/renderer.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/resources.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/shapes.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.gfx/types.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/ime_service.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/input_device_registry.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/input_reports.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/text_editing.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/text_input.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/usages.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.policy/presentation.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.wlan.service/wlan_service.fidl +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/include/lib/async/cpp/receiver.h +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/include/lib/async/cpp/task.h +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/include/lib/async/cpp/wait.h +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/receiver.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/task.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/trap.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/async-cpp/wait.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/async-default/include/lib/async/default.h +FILE: ../../../fuchsia/sdk/linux/pkg/async-loop-cpp/include/lib/async-loop/cpp/loop.h +FILE: ../../../fuchsia/sdk/linux/pkg/async-loop-cpp/loop_wrapper.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/async-loop/include/lib/async-loop/loop.h +FILE: ../../../fuchsia/sdk/linux/pkg/async-loop/loop.c +FILE: ../../../fuchsia/sdk/linux/pkg/async/include/lib/async/dispatcher.h +FILE: ../../../fuchsia/sdk/linux/pkg/async/include/lib/async/receiver.h +FILE: ../../../fuchsia/sdk/linux/pkg/async/include/lib/async/task.h +FILE: ../../../fuchsia/sdk/linux/pkg/async/include/lib/async/wait.h +FILE: ../../../fuchsia/sdk/linux/pkg/async/ops.c +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/limits.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/namespace.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/private.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/unsafe.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/decoding.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/encoding.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/formatting.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/coding.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/cpp/string_view.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/cpp/vector_view.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/include/lib/fidl/internal.h +FILE: ../../../fuchsia/sdk/linux/pkg/fidl_base/validating.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/function.h +FILE: ../../../fuchsia/sdk/linux/pkg/fit/include/lib/fit/function_internal.h +FILE: ../../../fuchsia/sdk/linux/pkg/memfs/include/lib/memfs/memfs.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/commands.cc +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/host_memory.cc +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/include/lib/ui/scenic/cpp/commands.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/include/lib/ui/scenic/cpp/host_memory.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/include/lib/ui/scenic/cpp/resources.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/include/lib/ui/scenic/cpp/session.h +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/resources.cc +FILE: ../../../fuchsia/sdk/linux/pkg/scenic_cpp/session.cc +FILE: ../../../fuchsia/sdk/linux/pkg/zx/fifo.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/fifo.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/handle.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/timer.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/timer.cpp +---------------------------------------------------------------------------------------------------- +Copyright 2017 The Fuchsia Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/dart/fidl/lib/fidl.dart + ../../../LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/fidl.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia/lib/fuchsia.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic_flutter/lib/child_view.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic_flutter/lib/child_view_connection.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_services/lib/src/startup_context.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/src/fakes/zircon_fakes.dart +FILE: ../../../fuchsia/sdk/linux/dart/zircon/lib/zircon.dart +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/collections_deprecated.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/formats_deprecated.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/image_formats.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/image_formats_deprecated.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sysmem/usages.fidl +---------------------------------------------------------------------------------------------------- +Copyright 2018 The Chromium Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/dart/fuchsia_services/lib/src/internal/_startup_context_impl.dart + ../../../LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_services/lib/src/internal/_startup_context_impl.dart +---------------------------------------------------------------------------------------------------- +Copyright 2019 The Chromium Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.netstack/netstack.fidl + ../../../LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.netstack/netstack.fidl +---------------------------------------------------------------------------------------------------- +Copyright 2013 The Chromium Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/component_controller.fidl + ../../../LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/component_controller.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/environment.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/environment_controller.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/launcher.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/loader.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.sys/runner.fidl +---------------------------------------------------------------------------------------------------- +Copyright 2016 The Chromium Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/input_event_constants.fidl + ../../../fuchsia/sdk/linux/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/input_event_constants.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.input/input_events.fidl +---------------------------------------------------------------------------------------------------- +Copyright 2014 The Fuchsia Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/view_manager.fidl + ../../../fuchsia/sdk/linux/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/view_manager.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/view_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/view_trees.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/views.fidl +---------------------------------------------------------------------------------------------------- +Copyright 2015 The Fuchsia Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../third_party/icu/scripts/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.oldhttp/http_error.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.oldhttp/http_header.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.oldhttp/http_service.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.oldhttp/url_loader.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.oldhttp/url_request.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.oldhttp/url_response.fidl +---------------------------------------------------------------------------------------------------- +Copyright 2015 The Chromium Authors. All rights reserved. + +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 Google Inc. 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: fuchsia_sdk +ORIGIN: ../../../third_party/tonic/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/assert.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/bootdata.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/boot/netboot.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/compiler.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/device/ioctl-wrapper.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/device/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/driver/binding.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/errors.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/i2c.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/usb.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/usb/audio.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/usb/hid.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/usb/hub.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/hw/usb/ums.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/listnode.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/pixelformat.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/processargs.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/status.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/debug.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/exception.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/log.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/object.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/pci.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/port.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/profile.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/resource.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/syscalls/types.h +FILE: ../../../fuchsia/sdk/linux/arch/arm64/sysroot/include/zircon/types.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/assert.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/boot/bootdata.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/boot/netboot.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/compiler.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/device/ioctl-wrapper.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/device/ioctl.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/driver/binding.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/errors.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/i2c.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/usb.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/usb/audio.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/usb/hid.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/usb/hub.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/hw/usb/ums.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/listnode.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/pixelformat.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/processargs.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/status.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/debug.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/exception.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/log.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/object.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/pci.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/port.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/profile.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/resource.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/syscalls/types.h +FILE: ../../../fuchsia/sdk/linux/arch/x64/sysroot/include/zircon/types.h +FILE: ../../../fuchsia/sdk/linux/dart/fidl/lib/src/interface.dart +FILE: ../../../fuchsia/sdk/linux/dart/fuchsia_scenic_flutter/lib/src/child_scene_layer.dart +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.fonts/font_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ledger/ledger.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.math/math.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.playback/problem.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media.playback/seeking_reader.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.media/audio.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/basemgr/base_shell.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/basemgr/user_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/context/context_reader.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/context/context_writer.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/context/value.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/context/value_type.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/module/module_context.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/module/module_controller.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/session/focus.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/session/session_shell.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/link.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_controller.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_info.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/story/story_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/suggestion/proposal.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/suggestion/proposal_publisher.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/suggestion/query_handler.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/suggestion/suggestion_display.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/suggestion/suggestion_engine.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/suggestion/suggestion_provider.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.modular/suggestion/user_input.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.net.oldhttp/url_body.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.policy/presenter.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/view_containers.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/view_properties.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1/view_tree_token.fidl +FILE: ../../../fuchsia/sdk/linux/fidl/fuchsia.ui.viewsv1token/view_token.fidl +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/fdio.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/io.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/vfs.h +FILE: ../../../fuchsia/sdk/linux/pkg/fdio/include/lib/fdio/watcher.h +FILE: ../../../fuchsia/sdk/linux/pkg/sync/include/lib/sync/completion.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/channel.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/event.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/eventpair.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/channel.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/event.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/eventpair.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/job.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/object.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/object_traits.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/port.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/process.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/socket.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/task.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/thread.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/time.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/vmar.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/include/lib/zx/vmo.h +FILE: ../../../fuchsia/sdk/linux/pkg/zx/job.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/port.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/process.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/socket.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/thread.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/vmar.cpp +FILE: ../../../fuchsia/sdk/linux/pkg/zx/vmo.cpp +---------------------------------------------------------------------------------------------------- +Copyright 2016 The Fuchsia Authors. All rights reserved. + +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 Google Inc. 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. +==================================================================================================== +Total license count: 13 diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 841dd181669a1..94d46ff05c176 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 9fbc0d30a3a9de96a9a329b406654e52 +Signature: 0be78831eab5d4a2ae50051976957bba UNUSED LICENSES: @@ -435,512 +435,477 @@ limitations under the License. ==================================================================================================== LIBRARY: gif ORIGIN: ../../../third_party/skia/third_party/gif/SkGifImageReader.cpp -TYPE: LicenseType.lgpl +TYPE: LicenseType.mpl FILE: ../../../third_party/skia/third_party/gif/SkGifImageReader.cpp FILE: ../../../third_party/skia/third_party/gif/SkGifImageReader.h ---------------------------------------------------------------------------------------------------- -GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - -Copyright (C) 1991, 1999 Free Software Foundation, Inc. -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! +MOZILLA PUBLIC LICENSE + Version 1.1 + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the MPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + https://www.mozilla.org/MPL + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] ==================================================================================================== ==================================================================================================== @@ -970,125 +935,6 @@ may be used: CompuServe Incorporated." ==================================================================================================== -==================================================================================================== -LIBRARY: harfbuzz -ORIGIN: ../../../third_party/skia/third_party/harfbuzz/hb-buffer-deserialize-json.hh -TYPE: LicenseType.unknown -FILE: ../../../third_party/skia/third_party/harfbuzz/hb-buffer-deserialize-json.hh -FILE: ../../../third_party/skia/third_party/harfbuzz/hb-buffer-deserialize-text.hh ----------------------------------------------------------------------------------------------------- -Copyright © 2013 Google, Inc. - - This is part of HarfBuzz, a text shaping library. - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that the -above copyright notice and the following two paragraphs appear in -all copies of this software. - -IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - -THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -==================================================================================================== - -==================================================================================================== -LIBRARY: harfbuzz -ORIGIN: ../../../third_party/skia/third_party/harfbuzz/hb-ot-shape-complex-indic-machine.hh -TYPE: LicenseType.unknown -FILE: ../../../third_party/skia/third_party/harfbuzz/hb-ot-shape-complex-indic-machine.hh -FILE: ../../../third_party/skia/third_party/harfbuzz/hb-ot-shape-complex-myanmar-machine.hh ----------------------------------------------------------------------------------------------------- -Copyright © 2011,2012 Google, Inc. - - This is part of HarfBuzz, a text shaping library. - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that the -above copyright notice and the following two paragraphs appear in -all copies of this software. - -IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - -THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -==================================================================================================== - -==================================================================================================== -LIBRARY: harfbuzz -ORIGIN: ../../../third_party/skia/third_party/harfbuzz/hb-ot-shape-complex-use-machine.hh -TYPE: LicenseType.unknown -FILE: ../../../third_party/skia/third_party/harfbuzz/hb-ot-shape-complex-use-machine.hh ----------------------------------------------------------------------------------------------------- -Copyright © 2015 Mozilla Foundation. -Copyright © 2015 Google, Inc. - - This is part of HarfBuzz, a text shaping library. - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that the -above copyright notice and the following two paragraphs appear in -all copies of this software. - -IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - -THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -==================================================================================================== - -==================================================================================================== -LIBRARY: harfbuzz -ORIGIN: ../../../third_party/skia/third_party/harfbuzz/hb-version.h -TYPE: LicenseType.unknown -FILE: ../../../third_party/skia/third_party/harfbuzz/hb-version.h ----------------------------------------------------------------------------------------------------- -Copyright © 2011 Google, Inc. - - This is part of HarfBuzz, a text shaping library. - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that the -above copyright notice and the following two paragraphs appear in -all copies of this software. - -IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - -THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -==================================================================================================== - ==================================================================================================== LIBRARY: libsdl LIBRARY: skia @@ -1161,8 +1007,7 @@ FILE: ../../../third_party/skia/fuzz/FuzzGradients.cpp FILE: ../../../third_party/skia/fuzz/FuzzMain.cpp FILE: ../../../third_party/skia/fuzz/FuzzParsePath.cpp FILE: ../../../third_party/skia/fuzz/FuzzPathop.cpp -FILE: ../../../third_party/skia/gm/OverStroke.cpp -FILE: ../../../third_party/skia/gm/animatedGif.cpp +FILE: ../../../third_party/skia/gm/animated_gif.cpp FILE: ../../../third_party/skia/gm/animatedimageblurs.cpp FILE: ../../../third_party/skia/gm/arcto.cpp FILE: ../../../third_party/skia/gm/bigrect.cpp @@ -1180,8 +1025,8 @@ FILE: ../../../third_party/skia/gm/croppedrects.cpp FILE: ../../../third_party/skia/gm/dashcircle.cpp FILE: ../../../third_party/skia/gm/drawregion.cpp FILE: ../../../third_party/skia/gm/drawregionmodes.cpp -FILE: ../../../third_party/skia/gm/encode-platform.cpp -FILE: ../../../third_party/skia/gm/encode-srgb.cpp +FILE: ../../../third_party/skia/gm/encode_platform.cpp +FILE: ../../../third_party/skia/gm/encode_srgb.cpp FILE: ../../../third_party/skia/gm/filterbug.cpp FILE: ../../../third_party/skia/gm/hardstop_gradients.cpp FILE: ../../../third_party/skia/gm/imagemakewithfilter.cpp @@ -1189,6 +1034,7 @@ FILE: ../../../third_party/skia/gm/imagemasksubset.cpp FILE: ../../../third_party/skia/gm/lattice.cpp FILE: ../../../third_party/skia/gm/lightingshader2.cpp FILE: ../../../third_party/skia/gm/overdrawcolorfilter.cpp +FILE: ../../../third_party/skia/gm/overstroke.cpp FILE: ../../../third_party/skia/gm/pathmaskcache.cpp FILE: ../../../third_party/skia/gm/readpixels.cpp FILE: ../../../third_party/skia/gm/rectangletexture.cpp @@ -1250,91 +1096,6 @@ FILE: ../../../third_party/skia/src/codec/SkRawCodec.cpp FILE: ../../../third_party/skia/src/codec/SkRawCodec.h FILE: ../../../third_party/skia/src/codec/SkStreamBuffer.cpp FILE: ../../../third_party/skia/src/codec/SkStreamBuffer.h -FILE: ../../../third_party/skia/src/compute/common/cl/assert_cl.c -FILE: ../../../third_party/skia/src/compute/common/cl/assert_cl.h -FILE: ../../../third_party/skia/src/compute/common/cuda/assert_cuda.c -FILE: ../../../third_party/skia/src/compute/common/cuda/assert_cuda.h -FILE: ../../../third_party/skia/src/compute/common/macros.h -FILE: ../../../third_party/skia/src/compute/common/util.c -FILE: ../../../third_party/skia/src/compute/common/util.h -FILE: ../../../third_party/skia/src/compute/common/vk/assert_vk.c -FILE: ../../../third_party/skia/src/compute/common/vk/assert_vk.h -FILE: ../../../third_party/skia/src/compute/hs/cl/bench/main.c -FILE: ../../../third_party/skia/src/compute/hs/cl/hs_cl.c -FILE: ../../../third_party/skia/src/compute/hs/cl/hs_cl.h -FILE: ../../../third_party/skia/src/compute/hs/cl/hs_cl_target.h -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_config.h -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_intel_gen8_u32.c -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_kernels.cl -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_target.h -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_config.h -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_intel_gen8_u64.c -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_kernels.cl -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_target.h -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/hs_cl_macros.h -FILE: ../../../third_party/skia/src/compute/hs/cuda/bench/main.c -FILE: ../../../third_party/skia/src/compute/hs/cuda/hs_cuda.inl -FILE: ../../../third_party/skia/src/compute/hs/cuda/sm_35/hs_cuda_macros.h -FILE: ../../../third_party/skia/src/compute/hs/cuda/sm_35/u32/hs_cuda_config.h -FILE: ../../../third_party/skia/src/compute/hs/cuda/sm_35/u32/hs_cuda_u32.cu -FILE: ../../../third_party/skia/src/compute/hs/cuda/sm_35/u64/hs_cuda_config.h -FILE: ../../../third_party/skia/src/compute/hs/cuda/sm_35/u64/hs_cuda_u64.cu -FILE: ../../../third_party/skia/src/compute/hs/gen/gen.h -FILE: ../../../third_party/skia/src/compute/hs/gen/main.c -FILE: ../../../third_party/skia/src/compute/hs/gen/networks.h -FILE: ../../../third_party/skia/src/compute/hs/gen/networks_merging.c -FILE: ../../../third_party/skia/src/compute/hs/gen/networks_sorting.c -FILE: ../../../third_party/skia/src/compute/hs/gen/target_cuda.c -FILE: ../../../third_party/skia/src/compute/hs/gen/target_glsl.c -FILE: ../../../third_party/skia/src/compute/hs/gen/target_opencl.c -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_amd_gcn_u32.c -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_config.h -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_modules.h -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_target.h -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_amd_gcn_u64.c -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_config.h -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_modules.h -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_target.h -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/hs_glsl_macros.h -FILE: ../../../third_party/skia/src/compute/hs/vk/bench/main.c -FILE: ../../../third_party/skia/src/compute/hs/vk/hs_glsl_macros.h -FILE: ../../../third_party/skia/src/compute/hs/vk/hs_glsl_preamble.h -FILE: ../../../third_party/skia/src/compute/hs/vk/hs_vk.c -FILE: ../../../third_party/skia/src/compute/hs/vk/hs_vk.h -FILE: ../../../third_party/skia/src/compute/hs/vk/hs_vk_target.h -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_config.h -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_intel_gen8_u32.c -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_modules.h -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_target.h -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_config.h -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_intel_gen8_u64.c -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_modules.h -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_target.h -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/hs_glsl_macros.h -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/hs_glsl_macros.h -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_config.h -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_modules.h -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_nvidia_sm35_u32.c -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_target.h -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_config.h -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_modules.h -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_nvidia_sm35_u64.c -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_target.h -FILE: ../../../third_party/skia/src/compute/sk/SkContext_Compute.cpp -FILE: ../../../third_party/skia/src/compute/sk/SkContext_Compute.h -FILE: ../../../third_party/skia/src/compute/sk/SkDevice_Compute.cpp -FILE: ../../../third_party/skia/src/compute/sk/SkImage_Compute.cpp -FILE: ../../../third_party/skia/src/compute/sk/SkImage_Compute.h -FILE: ../../../third_party/skia/src/compute/sk/SkSurface_Compute.cpp -FILE: ../../../third_party/skia/src/compute/sk/SkSurface_Compute.h -FILE: ../../../third_party/skia/src/compute/skc/assert_skc.c -FILE: ../../../third_party/skia/src/compute/skc/assert_skc.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/render.cl -FILE: ../../../third_party/skia/src/compute/skc/styling.c -FILE: ../../../third_party/skia/src/compute/skc/styling.h -FILE: ../../../third_party/skia/src/compute/skc/styling_types.h -FILE: ../../../third_party/skia/src/compute/skc/tile.h -FILE: ../../../third_party/skia/src/core/Sk4x4f.h FILE: ../../../third_party/skia/src/core/SkATrace.cpp FILE: ../../../third_party/skia/src/core/SkATrace.h FILE: ../../../third_party/skia/src/core/SkAnnotationKeys.h @@ -1344,7 +1105,7 @@ FILE: ../../../third_party/skia/src/core/SkAutoPixmapStorage.cpp FILE: ../../../third_party/skia/src/core/SkAutoPixmapStorage.h FILE: ../../../third_party/skia/src/core/SkBlendModePriv.h FILE: ../../../third_party/skia/src/core/SkClipOpPriv.h -FILE: ../../../third_party/skia/src/core/SkColorMatrixFilterRowMajor255.h +FILE: ../../../third_party/skia/src/core/SkColorFilter_Matrix.h FILE: ../../../third_party/skia/src/core/SkColorSpace.cpp FILE: ../../../third_party/skia/src/core/SkColorSpacePriv.h FILE: ../../../third_party/skia/src/core/SkCpu.cpp @@ -1358,11 +1119,6 @@ FILE: ../../../third_party/skia/src/core/SkICCPriv.h FILE: ../../../third_party/skia/src/core/SkImageFilterCache.cpp FILE: ../../../third_party/skia/src/core/SkImageFilterCache.h FILE: ../../../third_party/skia/src/core/SkLRUCache.h -FILE: ../../../third_party/skia/src/core/SkLights.cpp -FILE: ../../../third_party/skia/src/core/SkLiteDL.cpp -FILE: ../../../third_party/skia/src/core/SkLiteDL.h -FILE: ../../../third_party/skia/src/core/SkLiteRecorder.cpp -FILE: ../../../third_party/skia/src/core/SkLiteRecorder.h FILE: ../../../third_party/skia/src/core/SkMSAN.h FILE: ../../../third_party/skia/src/core/SkMakeUnique.h FILE: ../../../third_party/skia/src/core/SkMatrixPriv.h @@ -1394,8 +1150,6 @@ FILE: ../../../third_party/skia/src/gpu/GrAppliedClip.h FILE: ../../../third_party/skia/src/gpu/GrAuditTrail.cpp FILE: ../../../third_party/skia/src/gpu/GrBitmapTextureMaker.cpp FILE: ../../../third_party/skia/src/gpu/GrBitmapTextureMaker.h -FILE: ../../../third_party/skia/src/gpu/GrBuffer.cpp -FILE: ../../../third_party/skia/src/gpu/GrBuffer.h FILE: ../../../third_party/skia/src/gpu/GrClipStackClip.cpp FILE: ../../../third_party/skia/src/gpu/GrClipStackClip.h FILE: ../../../third_party/skia/src/gpu/GrColorSpaceXform.cpp @@ -1449,8 +1203,6 @@ FILE: ../../../third_party/skia/src/gpu/effects/GrShadowGeoProc.h FILE: ../../../third_party/skia/src/gpu/gl/GrGLBuffer.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLBuffer.h FILE: ../../../third_party/skia/src/gpu/gl/GrGLGpuCommandBuffer.h -FILE: ../../../third_party/skia/src/gpu/gl/GrGLTestInterface.cpp -FILE: ../../../third_party/skia/src/gpu/gl/GrGLTestInterface.h FILE: ../../../third_party/skia/src/gpu/gl/glfw/GrGLMakeNativeInterface_glfw.cpp FILE: ../../../third_party/skia/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h FILE: ../../../third_party/skia/src/gpu/glsl/GrGLSLProgramDataManager.cpp @@ -1502,7 +1254,6 @@ FILE: ../../../third_party/skia/src/opts/SkOpts_crc32.cpp FILE: ../../../third_party/skia/src/opts/SkOpts_sse42.cpp FILE: ../../../third_party/skia/src/opts/SkSwizzler_opts.h FILE: ../../../third_party/skia/src/pdf/SkBitmapKey.h -FILE: ../../../third_party/skia/src/pdf/SkPDFConvertType1FontStream.h FILE: ../../../third_party/skia/src/pdf/SkPDFDocumentPriv.h FILE: ../../../third_party/skia/src/pdf/SkPDFMakeCIDGlyphWidthsArray.cpp FILE: ../../../third_party/skia/src/pdf/SkPDFMakeCIDGlyphWidthsArray.h @@ -1513,6 +1264,7 @@ FILE: ../../../third_party/skia/src/ports/SkImageGeneratorCG.cpp FILE: ../../../third_party/skia/src/ports/SkImageGeneratorWIC.cpp FILE: ../../../third_party/skia/src/shaders/SkColorFilterShader.h FILE: ../../../third_party/skia/src/shaders/SkColorShader.cpp +FILE: ../../../third_party/skia/src/shaders/SkLights.cpp FILE: ../../../third_party/skia/src/shaders/gradients/Sk4fGradientBase.cpp FILE: ../../../third_party/skia/src/shaders/gradients/Sk4fGradientBase.h FILE: ../../../third_party/skia/src/shaders/gradients/Sk4fGradientPriv.h @@ -1565,6 +1317,7 @@ FILE: ../../../third_party/skia/src/sksl/ast/SkSLASTIntLiteral.h FILE: ../../../third_party/skia/src/sksl/ast/SkSLASTInterfaceBlock.h FILE: ../../../third_party/skia/src/sksl/ast/SkSLASTModifiersDeclaration.h FILE: ../../../third_party/skia/src/sksl/ast/SkSLASTNode.h +FILE: ../../../third_party/skia/src/sksl/ast/SkSLASTNullLiteral.h FILE: ../../../third_party/skia/src/sksl/ast/SkSLASTParameter.h FILE: ../../../third_party/skia/src/sksl/ast/SkSLASTPositionNode.h FILE: ../../../third_party/skia/src/sksl/ast/SkSLASTPrecision.h @@ -1607,6 +1360,7 @@ FILE: ../../../third_party/skia/src/sksl/ir/SkSLLayout.h FILE: ../../../third_party/skia/src/sksl/ir/SkSLModifiers.h FILE: ../../../third_party/skia/src/sksl/ir/SkSLModifiersDeclaration.h FILE: ../../../third_party/skia/src/sksl/ir/SkSLNop.h +FILE: ../../../third_party/skia/src/sksl/ir/SkSLNullLiteral.h FILE: ../../../third_party/skia/src/sksl/ir/SkSLPostfixExpression.h FILE: ../../../third_party/skia/src/sksl/ir/SkSLPrefixExpression.h FILE: ../../../third_party/skia/src/sksl/ir/SkSLProgram.h @@ -1679,8 +1433,7 @@ FILE: ../../../third_party/skia/bench/JSONBench.cpp FILE: ../../../third_party/skia/bench/PathOpsBench.cpp FILE: ../../../third_party/skia/bench/PolyUtilsBench.cpp FILE: ../../../third_party/skia/bench/ShaderMaskFilterBench.cpp -FILE: ../../../third_party/skia/experimental/nima/NimaActor.cpp -FILE: ../../../third_party/skia/experimental/nima/NimaActor.h +FILE: ../../../third_party/skia/bench/TypefaceBench.cpp FILE: ../../../third_party/skia/experimental/pvg/draw_msg.proto FILE: ../../../third_party/skia/fuzz/FuzzCommon.cpp FILE: ../../../third_party/skia/fuzz/FuzzPathMeasure.cpp @@ -1689,7 +1442,6 @@ FILE: ../../../third_party/skia/fuzz/oss_fuzz/FuzzImageFilterDeserialize.cpp FILE: ../../../third_party/skia/fuzz/oss_fuzz/FuzzPathDeserialize.cpp FILE: ../../../third_party/skia/fuzz/oss_fuzz/FuzzRegionDeserialize.cpp FILE: ../../../third_party/skia/fuzz/oss_fuzz/FuzzRegionSetPath.cpp -FILE: ../../../third_party/skia/gm/3dgm.cpp FILE: ../../../third_party/skia/gm/analytic_gradients.cpp FILE: ../../../third_party/skia/gm/androidblendmodes.cpp FILE: ../../../third_party/skia/gm/b_119394958.cpp @@ -1708,7 +1460,7 @@ FILE: ../../../third_party/skia/gm/fwidth_squircle.cpp FILE: ../../../third_party/skia/gm/gradients_degenerate.cpp FILE: ../../../third_party/skia/gm/hugepath.cpp FILE: ../../../third_party/skia/gm/localmatrixshader.cpp -FILE: ../../../third_party/skia/gm/makeRasterImage.cpp +FILE: ../../../third_party/skia/gm/make_raster_image.cpp FILE: ../../../third_party/skia/gm/mandoline.cpp FILE: ../../../third_party/skia/gm/orientation.cpp FILE: ../../../third_party/skia/gm/p3.cpp @@ -1727,7 +1479,9 @@ FILE: ../../../third_party/skia/include/android/SkAnimatedImage.h FILE: ../../../third_party/skia/include/c/sk_colorspace.h FILE: ../../../third_party/skia/include/c/sk_imageinfo.h FILE: ../../../third_party/skia/include/core/SkCanvasVirtualEnforcer.h +FILE: ../../../third_party/skia/include/core/SkContourMeasure.h FILE: ../../../third_party/skia/include/core/SkCoverageMode.h +FILE: ../../../third_party/skia/include/core/SkCubicMap.h FILE: ../../../third_party/skia/include/core/SkFontMetrics.h FILE: ../../../third_party/skia/include/core/SkFontParameters.h FILE: ../../../third_party/skia/include/core/SkFontTypes.h @@ -1747,10 +1501,12 @@ FILE: ../../../third_party/skia/include/private/GrVkTypesPriv.h FILE: ../../../third_party/skia/include/private/SkMacros.h FILE: ../../../third_party/skia/include/private/SkSafe32.h FILE: ../../../third_party/skia/include/private/SkTo.h +FILE: ../../../third_party/skia/include/third_party/skcms/skcms.h FILE: ../../../third_party/skia/include/utils/Sk3D.h FILE: ../../../third_party/skia/include/utils/SkAnimCodecPlayer.h FILE: ../../../third_party/skia/include/utils/SkTextUtils.h FILE: ../../../third_party/skia/infra/cts/run_testlab.go +FILE: ../../../third_party/skia/modules/skottie/gm/3dgm.cpp FILE: ../../../third_party/skia/modules/skottie/include/SkottieProperty.h FILE: ../../../third_party/skia/modules/skottie/src/SkottieAdapter.cpp FILE: ../../../third_party/skia/modules/skottie/src/SkottieAdapter.h @@ -1763,8 +1519,8 @@ FILE: ../../../third_party/skia/modules/skottie/src/SkottiePriv.h FILE: ../../../third_party/skia/modules/skottie/src/SkottieProperty.cpp FILE: ../../../third_party/skia/modules/skottie/src/SkottieShapeLayer.cpp FILE: ../../../third_party/skia/modules/skottie/src/SkottieTest.cpp -FILE: ../../../third_party/skia/modules/skottie/src/SkottieTextLayer.cpp FILE: ../../../third_party/skia/modules/skottie/src/SkottieTool.cpp +FILE: ../../../third_party/skia/modules/skottie/src/text/TextLayer.cpp FILE: ../../../third_party/skia/modules/skottie/utils/SkottieUtils.cpp FILE: ../../../third_party/skia/modules/skottie/utils/SkottieUtils.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGClipEffect.h @@ -1794,59 +1550,27 @@ FILE: ../../../third_party/skia/samplecode/SampleAnimatedImage.cpp FILE: ../../../third_party/skia/samplecode/SampleCusp.cpp FILE: ../../../third_party/skia/samplecode/SampleFlutterAnimate.cpp FILE: ../../../third_party/skia/samplecode/SampleGlyphTransform.cpp -FILE: ../../../third_party/skia/samplecode/SampleNima.cpp FILE: ../../../third_party/skia/src/android/SkAnimatedImage.cpp FILE: ../../../third_party/skia/src/c/sk_imageinfo.cpp FILE: ../../../third_party/skia/src/codec/SkEncodedInfo.cpp FILE: ../../../third_party/skia/src/codec/SkOrientationMarker.cpp FILE: ../../../third_party/skia/src/codec/SkWuffsCodec.cpp FILE: ../../../third_party/skia/src/codec/SkWuffsCodec.h -FILE: ../../../third_party/skia/src/compute/common/cl/find_cl.c -FILE: ../../../third_party/skia/src/compute/common/cl/find_cl.h -FILE: ../../../third_party/skia/src/compute/common/vk/cache_vk.c -FILE: ../../../third_party/skia/src/compute/common/vk/cache_vk.h -FILE: ../../../third_party/skia/src/compute/common/vk/event_pool.c -FILE: ../../../third_party/skia/src/compute/common/vk/event_pool.h -FILE: ../../../third_party/skia/src/compute/common/vk/host_alloc.c -FILE: ../../../third_party/skia/src/compute/common/vk/host_alloc.h -FILE: ../../../third_party/skia/src/compute/hs/cl/bench/sort.cpp -FILE: ../../../third_party/skia/src/compute/hs/cuda/bench/sort.cpp -FILE: ../../../third_party/skia/src/compute/hs/cuda/sm_35/u32/hs_cuda.h -FILE: ../../../third_party/skia/src/compute/hs/cuda/sm_35/u64/hs_cuda.h -FILE: ../../../third_party/skia/src/compute/hs/gen/target_debug.c -FILE: ../../../third_party/skia/src/compute/hs/gen/transpose.c -FILE: ../../../third_party/skia/src/compute/hs/gen/transpose.h -FILE: ../../../third_party/skia/src/compute/hs/vk/bench/sort.cpp -FILE: ../../../third_party/skia/src/compute/skc/allocator_host.c -FILE: ../../../third_party/skia/src/compute/skc/allocator_host.h -FILE: ../../../third_party/skia/src/compute/skc/interop.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/allocator_device_cl.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/allocator_device_cl.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/interop/interop_glfw.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/segment_ttck.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/segment_ttrk.cl -FILE: ../../../third_party/skia/src/compute/skc/runtime.h -FILE: ../../../third_party/skia/src/compute/skc/skc_err.h -FILE: ../../../third_party/skia/src/compute/skc/skc_types.h -FILE: ../../../third_party/skia/src/compute/skc/suballocator.c -FILE: ../../../third_party/skia/src/compute/skc/suballocator.h -FILE: ../../../third_party/skia/src/compute/ts/transform_stack.c -FILE: ../../../third_party/skia/src/compute/ts/transform_stack.h FILE: ../../../third_party/skia/src/core/SkBlurPriv.h FILE: ../../../third_party/skia/src/core/SkCanvasPriv.cpp FILE: ../../../third_party/skia/src/core/SkColorSpaceXformSteps.cpp FILE: ../../../third_party/skia/src/core/SkColorSpaceXformSteps.h +FILE: ../../../third_party/skia/src/core/SkContourMeasure.cpp FILE: ../../../third_party/skia/src/core/SkCoverageModePriv.h FILE: ../../../third_party/skia/src/core/SkCubicMap.cpp -FILE: ../../../third_party/skia/src/core/SkCubicMap.h FILE: ../../../third_party/skia/src/core/SkDeferredDisplayList.cpp FILE: ../../../third_party/skia/src/core/SkDeferredDisplayListPriv.h FILE: ../../../third_party/skia/src/core/SkDraw_text.cpp +FILE: ../../../third_party/skia/src/core/SkFontPriv.cpp FILE: ../../../third_party/skia/src/core/SkFontPriv.h FILE: ../../../third_party/skia/src/core/SkGlyph.cpp FILE: ../../../third_party/skia/src/core/SkIPoint16.h FILE: ../../../third_party/skia/src/core/SkMaskFilterBase.h -FILE: ../../../third_party/skia/src/core/SkPaint_text.cpp FILE: ../../../third_party/skia/src/core/SkPath_serial.cpp FILE: ../../../third_party/skia/src/core/SkPicturePriv.h FILE: ../../../third_party/skia/src/core/SkRRectPriv.h @@ -1871,9 +1595,9 @@ FILE: ../../../third_party/skia/src/gpu/GrContextThreadSafeProxyPriv.h FILE: ../../../third_party/skia/src/gpu/GrDDLContext.cpp FILE: ../../../third_party/skia/src/gpu/GrDeinstantiateProxyTracker.cpp FILE: ../../../third_party/skia/src/gpu/GrDeinstantiateProxyTracker.h -FILE: ../../../third_party/skia/src/gpu/GrDirectContext.cpp FILE: ../../../third_party/skia/src/gpu/GrDriverBugWorkarounds.cpp FILE: ../../../third_party/skia/src/gpu/GrFPArgs.h +FILE: ../../../third_party/skia/src/gpu/GrLegacyDirectContext.cpp FILE: ../../../third_party/skia/src/gpu/GrProxyProvider.cpp FILE: ../../../third_party/skia/src/gpu/GrProxyProvider.h FILE: ../../../third_party/skia/src/gpu/GrQuad.cpp @@ -1893,74 +1617,74 @@ FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCStrokeGeometry.cpp FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCStrokeGeometry.h FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCStroker.cpp FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCStroker.h -FILE: ../../../third_party/skia/src/gpu/effects/GrAARectEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrAARectEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrAARectEffect.h -FILE: ../../../third_party/skia/src/gpu/effects/GrAlphaThresholdFragmentProcessor.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrAlphaThresholdFragmentProcessor.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrAlphaThresholdFragmentProcessor.h -FILE: ../../../third_party/skia/src/gpu/effects/GrCircleBlurFragmentProcessor.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrCircleBlurFragmentProcessor.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrCircleBlurFragmentProcessor.h -FILE: ../../../third_party/skia/src/gpu/effects/GrConfigConversionEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrConfigConversionEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrConfigConversionEffect.h -FILE: ../../../third_party/skia/src/gpu/effects/GrConstColorProcessor.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrConstColorProcessor.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrConstColorProcessor.h -FILE: ../../../third_party/skia/src/gpu/effects/GrLumaColorFilterEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrLumaColorFilterEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrLumaColorFilterEffect.h -FILE: ../../../third_party/skia/src/gpu/effects/GrMagnifierEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrMagnifierEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrMagnifierEffect.h -FILE: ../../../third_party/skia/src/gpu/effects/GrPremulInputFragmentProcessor.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrPremulInputFragmentProcessor.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrPremulInputFragmentProcessor.h -FILE: ../../../third_party/skia/src/gpu/effects/GrRRectBlurEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrRRectBlurEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrRRectBlurEffect.h -FILE: ../../../third_party/skia/src/gpu/effects/GrRectBlurEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrRectBlurEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrRectBlurEffect.h FILE: ../../../third_party/skia/src/gpu/effects/GrSkSLFP.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrSkSLFP.h FILE: ../../../third_party/skia/src/gpu/effects/GrYUVtoRGBEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrYUVtoRGBEffect.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrClampedGradientEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrAARectEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrAARectEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrConfigConversionEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrConfigConversionEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrConstColorProcessor.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrConstColorProcessor.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrLumaColorFilterEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrLumaColorFilterEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrMagnifierEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrMagnifierEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrPremulInputFragmentProcessor.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrPremulInputFragmentProcessor.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrRRectBlurEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrRRectBlurEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrRectBlurEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrRectBlurEffect.h FILE: ../../../third_party/skia/src/gpu/gradients/GrClampedGradientEffect.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrClampedGradientEffect.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrDualIntervalGradientColorizer.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrDualIntervalGradientColorizer.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrDualIntervalGradientColorizer.h FILE: ../../../third_party/skia/src/gpu/gradients/GrGradientBitmapCache.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrGradientBitmapCache.h FILE: ../../../third_party/skia/src/gpu/gradients/GrGradientShader.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrGradientShader.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrLinearGradientLayout.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrLinearGradientLayout.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrLinearGradientLayout.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrRadialGradientLayout.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrRadialGradientLayout.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrRadialGradientLayout.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrSingleIntervalGradientColorizer.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrSingleIntervalGradientColorizer.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrSingleIntervalGradientColorizer.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrSweepGradientLayout.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrSweepGradientLayout.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrSweepGradientLayout.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrTextureGradientColorizer.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrTextureGradientColorizer.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrTextureGradientColorizer.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrTiledGradientEffect.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrTiledGradientEffect.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrTiledGradientEffect.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrTwoPointConicalGradientLayout.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrTwoPointConicalGradientLayout.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrTwoPointConicalGradientLayout.h -FILE: ../../../third_party/skia/src/gpu/gradients/GrUnrolledBinaryGradientColorizer.cpp FILE: ../../../third_party/skia/src/gpu/gradients/GrUnrolledBinaryGradientColorizer.fp -FILE: ../../../third_party/skia/src/gpu/gradients/GrUnrolledBinaryGradientColorizer.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrClampedGradientEffect.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrClampedGradientEffect.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrDualIntervalGradientColorizer.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrDualIntervalGradientColorizer.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrLinearGradientLayout.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrLinearGradientLayout.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrRadialGradientLayout.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrRadialGradientLayout.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrSingleIntervalGradientColorizer.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrSingleIntervalGradientColorizer.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrSweepGradientLayout.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrSweepGradientLayout.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrTextureGradientColorizer.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrTextureGradientColorizer.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrTiledGradientEffect.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrTiledGradientEffect.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrTwoPointConicalGradientLayout.h +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrUnrolledBinaryGradientColorizer.cpp +FILE: ../../../third_party/skia/src/gpu/gradients/generated/GrUnrolledBinaryGradientColorizer.h FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlBuffer.h FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlBuffer.mm FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlCopyManager.h @@ -1968,6 +1692,7 @@ FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlCopyManager.mm FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlCopyPipelineState.h FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlCopyPipelineState.mm FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlCppUtil.h +FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlDepthStencil.mm FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlGpuCommandBuffer.h FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlGpuCommandBuffer.mm FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlPipelineState.h @@ -1988,12 +1713,12 @@ FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlUniformHandler.h FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlUniformHandler.mm FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlVaryingHandler.h FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlVaryingHandler.mm -FILE: ../../../third_party/skia/src/gpu/ops/GrAAFillRRectOp.cpp -FILE: ../../../third_party/skia/src/gpu/ops/GrAAFillRRectOp.h FILE: ../../../third_party/skia/src/gpu/ops/GrClearStencilClipOp.cpp FILE: ../../../third_party/skia/src/gpu/ops/GrDebugMarkerOp.cpp FILE: ../../../third_party/skia/src/gpu/ops/GrDrawableOp.cpp FILE: ../../../third_party/skia/src/gpu/ops/GrDrawableOp.h +FILE: ../../../third_party/skia/src/gpu/ops/GrFillRRectOp.cpp +FILE: ../../../third_party/skia/src/gpu/ops/GrFillRRectOp.h FILE: ../../../third_party/skia/src/gpu/ops/GrFillRectOp.cpp FILE: ../../../third_party/skia/src/gpu/ops/GrFillRectOp.h FILE: ../../../third_party/skia/src/gpu/ops/GrQuadPerEdgeAA.cpp @@ -2047,7 +1772,6 @@ FILE: ../../../third_party/skia/src/utils/SkTextUtils.cpp FILE: ../../../third_party/skia/src/utils/mac/SkUniqueCFRef.h FILE: ../../../third_party/skia/src/utils/win/SkDWriteNTDDI_VERSION.h FILE: ../../../third_party/skia/third_party/skcms/skcms.cc -FILE: ../../../third_party/skia/third_party/skcms/skcms.h FILE: ../../../third_party/skia/third_party/skcms/skcms_internal.h FILE: ../../../third_party/skia/third_party/skcms/src/Transform_inl.h FILE: ../../../third_party/skia/third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.cpp @@ -2084,7 +1808,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skcms -ORIGIN: ../../../third_party/skia/include/third_party/vulkan/LICENSE +ORIGIN: ../../../third_party/skia/include/third_party/skcms/LICENSE TYPE: LicenseType.bsd FILE: ../../../third_party/skia/third_party/skcms/version.sha1 ---------------------------------------------------------------------------------------------------- @@ -2159,7 +1883,6 @@ TYPE: LicenseType.bsd FILE: ../../../third_party/skia/.clang-tidy FILE: ../../../third_party/skia/CQ_COMMITTERS FILE: ../../../third_party/skia/DEPS -FILE: ../../../third_party/skia/Doxyfile FILE: ../../../third_party/skia/animations/checkbox.xml FILE: ../../../third_party/skia/animations/chest#1.jpg FILE: ../../../third_party/skia/animations/fire#1.jpg @@ -2172,83 +1895,12 @@ FILE: ../../../third_party/skia/animations/redcross#1.jpg FILE: ../../../third_party/skia/animations/text#1.xml FILE: ../../../third_party/skia/bench/microbench.json FILE: ../../../third_party/skia/bench/skpbench.json +FILE: ../../../third_party/skia/docker/binary-size/Dockerfile +FILE: ../../../third_party/skia/docker/cmake-release/Dockerfile FILE: ../../../third_party/skia/docker/skia-release/Dockerfile FILE: ../../../third_party/skia/docker/skia-wasm-release/Dockerfile FILE: ../../../third_party/skia/docker/skia-with-swift-shader-base/Dockerfile FILE: ../../../third_party/skia/docker/skia-with-swift-shader-base/build-with-swift-shader-and-run -FILE: ../../../third_party/skia/docs/SkAutoCanvasRestore_Reference.bmh -FILE: ../../../third_party/skia/docs/SkBitmap_Reference.bmh -FILE: ../../../third_party/skia/docs/SkBlendMode_Overview.bmh -FILE: ../../../third_party/skia/docs/SkBlendMode_Reference.bmh -FILE: ../../../third_party/skia/docs/SkCanvas_Reference.bmh -FILE: ../../../third_party/skia/docs/SkColor4f_Reference.bmh -FILE: ../../../third_party/skia/docs/SkColor_Reference.bmh -FILE: ../../../third_party/skia/docs/SkDynamicMemoryWStream_Reference.bmh -FILE: ../../../third_party/skia/docs/SkFILEStream_Reference.bmh -FILE: ../../../third_party/skia/docs/SkFILEWStream_Reference.bmh -FILE: ../../../third_party/skia/docs/SkFont_Reference.bmh -FILE: ../../../third_party/skia/docs/SkIPoint_Reference.bmh -FILE: ../../../third_party/skia/docs/SkIRect_Reference.bmh -FILE: ../../../third_party/skia/docs/SkImageInfo_Reference.bmh -FILE: ../../../third_party/skia/docs/SkImage_Reference.bmh -FILE: ../../../third_party/skia/docs/SkMatrix_Reference.bmh -FILE: ../../../third_party/skia/docs/SkMemoryStream_Reference.bmh -FILE: ../../../third_party/skia/docs/SkPaint_Reference.bmh -FILE: ../../../third_party/skia/docs/SkPath_Overview.bmh -FILE: ../../../third_party/skia/docs/SkPath_Reference.bmh -FILE: ../../../third_party/skia/docs/SkPicture_Reference.bmh -FILE: ../../../third_party/skia/docs/SkPixmap_Reference.bmh -FILE: ../../../third_party/skia/docs/SkPoint_Reference.bmh -FILE: ../../../third_party/skia/docs/SkRRect_Reference.bmh -FILE: ../../../third_party/skia/docs/SkRect_Reference.bmh -FILE: ../../../third_party/skia/docs/SkRegion_Reference.bmh -FILE: ../../../third_party/skia/docs/SkStream_Reference.bmh -FILE: ../../../third_party/skia/docs/SkSurface_Reference.bmh -FILE: ../../../third_party/skia/docs/SkTextBlobBuilder_Reference.bmh -FILE: ../../../third_party/skia/docs/SkTextBlob_Reference.bmh -FILE: ../../../third_party/skia/docs/SkWStream_Reference.bmh -FILE: ../../../third_party/skia/docs/illustrations.bmh -FILE: ../../../third_party/skia/docs/markup.bmh -FILE: ../../../third_party/skia/docs/overview.bmh -FILE: ../../../third_party/skia/docs/status.json -FILE: ../../../third_party/skia/docs/undocumented.bmh -FILE: ../../../third_party/skia/docs/usingBookmaker.bmh -FILE: ../../../third_party/skia/experimental/canvaskit/canvaskit/Roboto-Regular.ttf -FILE: ../../../third_party/skia/experimental/canvaskit/canvaskit/Roboto-Regular.woff -FILE: ../../../third_party/skia/experimental/canvaskit/canvaskit/example.html -FILE: ../../../third_party/skia/experimental/canvaskit/canvaskit/node.example.js -FILE: ../../../third_party/skia/experimental/canvaskit/canvaskit/package.json -FILE: ../../../third_party/skia/experimental/canvaskit/canvaskit/test.png -FILE: ../../../third_party/skia/experimental/canvaskit/cpu.js -FILE: ../../../third_party/skia/experimental/canvaskit/debug.js -FILE: ../../../third_party/skia/experimental/canvaskit/externs.js -FILE: ../../../third_party/skia/experimental/canvaskit/fonts/NotoMono-Regular.ttf -FILE: ../../../third_party/skia/experimental/canvaskit/gpu.js -FILE: ../../../third_party/skia/experimental/canvaskit/helper.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/_namedcolors.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/canvas2dcontext.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/color.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/font.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/htmlcanvas.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/imagedata.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/lineargradient.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/path2d.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/pattern.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/postamble.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/preamble.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/radialgradient.js -FILE: ../../../third_party/skia/experimental/canvaskit/htmlcanvas/util.js -FILE: ../../../third_party/skia/experimental/canvaskit/interface.js -FILE: ../../../third_party/skia/experimental/canvaskit/karma.bench.conf.js -FILE: ../../../third_party/skia/experimental/canvaskit/karma.conf.js -FILE: ../../../third_party/skia/experimental/canvaskit/package.json -FILE: ../../../third_party/skia/experimental/canvaskit/perf/animation.bench.js -FILE: ../../../third_party/skia/experimental/canvaskit/perf/assets/confetti.json -FILE: ../../../third_party/skia/experimental/canvaskit/perf/assets/drinks.json -FILE: ../../../third_party/skia/experimental/canvaskit/perf/assets/lego_loader.json -FILE: ../../../third_party/skia/experimental/canvaskit/perf/assets/onboarding.json -FILE: ../../../third_party/skia/experimental/canvaskit/ready.js -FILE: ../../../third_party/skia/experimental/canvaskit/release.js FILE: ../../../third_party/skia/experimental/docs/animationCommon.js FILE: ../../../third_party/skia/experimental/docs/backend.js FILE: ../../../third_party/skia/experimental/docs/canvasBackend.js @@ -2258,7 +1910,18 @@ FILE: ../../../third_party/skia/experimental/docs/jsonbaseddoc.htm FILE: ../../../third_party/skia/experimental/docs/svgBackend.js FILE: ../../../third_party/skia/experimental/docs/svgbaseddoc.htm FILE: ../../../third_party/skia/experimental/docs/utilities.js -FILE: ../../../third_party/skia/infra/bots/android_bin.isolate +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/cpu.js +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/debugger/index.html +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/debugger/sample.skp +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/externs.js +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/fonts/NotoMono-Regular.ttf +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/gpu.js +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/helper.js +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/karma.conf.js +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/package.json +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/ready.js +FILE: ../../../third_party/skia/go.mod +FILE: ../../../third_party/skia/go.sum FILE: ../../../third_party/skia/infra/bots/assets.isolate FILE: ../../../third_party/skia/infra/bots/assets/android_ndk_darwin/VERSION FILE: ../../../third_party/skia/infra/bots/assets/android_ndk_linux/VERSION @@ -2272,9 +1935,9 @@ FILE: ../../../third_party/skia/infra/bots/assets/chromebook_x86_64_gles/VERSION FILE: ../../../third_party/skia/infra/bots/assets/clang_linux/VERSION FILE: ../../../third_party/skia/infra/bots/assets/clang_win/VERSION FILE: ../../../third_party/skia/infra/bots/assets/cmake_linux/VERSION +FILE: ../../../third_party/skia/infra/bots/assets/cmake_mac/VERSION FILE: ../../../third_party/skia/infra/bots/assets/gcloud_linux/VERSION FILE: ../../../third_party/skia/infra/bots/assets/go/VERSION -FILE: ../../../third_party/skia/infra/bots/assets/go_deps/VERSION FILE: ../../../third_party/skia/infra/bots/assets/linux_vulkan_sdk/VERSION FILE: ../../../third_party/skia/infra/bots/assets/lottie-samples/VERSION FILE: ../../../third_party/skia/infra/bots/assets/mesa_intel_driver_linux/VERSION @@ -2316,7 +1979,9 @@ FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.ex FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Debug-SK_CPU_LIMIT_SSE41.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Debug-SafeStack.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Debug-Tidy.json +FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Debug-Wuffs.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Release-ASAN.json +FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Release-CMake.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Release-Fast.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Release-NoDEPS.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Debian9-Clang-x86_64-Release-Static.json @@ -2343,6 +2008,7 @@ FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.ex FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Win-Clang-x86-Debug-Exceptions.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Win-Clang-x86_64-Debug-OpenCL.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Win-Clang-x86_64-Release-Vulkan.json +FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Build-Win-MSVC-x86_64-Debug-MSRTC.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Housekeeper-PerCommit-CheckGeneratedFiles.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/build/examples/full.expected/Test-Debian9-Clang-GCE-CPU-AVX2-universal-devrel-All-Android_SKQP.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/builder_name_schema/builder_name_schema.json @@ -2357,12 +2023,14 @@ FILE: ../../../third_party/skia/infra/bots/recipe_modules/checkout/examples/full FILE: ../../../third_party/skia/infra/bots/recipe_modules/checkout/examples/full.expected/trybot.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/doxygen/examples/full.expected/doxygen.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/env/examples/full.expected/test.json +FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Perf-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-All-Android_SkottieTracing.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Perf-Android-Clang-GalaxyS7_G930FD-GPU-MaliT880-arm64-Debug-All-Android.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Perf-Android-Clang-Nexus5x-GPU-Adreno418-arm64-Debug-All-Android.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Perf-ChromeOS-Clang-SamsungChromebookPlus-GPU-MaliT860-arm-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Perf-Chromecast-Clang-Chorizo-CPU-Cortex_A7-arm-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Perf-Debian9-Clang-GCE-CPU-AVX2-x86_64-Debug-All-MSAN.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Perf-Debian9-Clang-GCE-CPU-AVX2-x86_64-Release-All-ASAN.json +FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Perf-Win2016-Clang-GCE-CPU-AVX2-x86_64-Debug-All-UBSAN.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-All-Android.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Android-Clang-GalaxyS7_G930FD-GPU-MaliT880-arm64-Debug-All-Android.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Android-Clang-Nexus5x-GPU-Adreno418-arm64-Debug-All-Android.json @@ -2374,9 +2042,10 @@ FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.e FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Debian9-Clang-GCE-GPU-SwiftShader-x86_64-Debug-All-SwiftShader.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All-OpenCL.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All-Vulkan.json -FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Mac-Clang-MacBookPro11.5-CPU-AVX2-x86_64-Debug-All-ASAN.json +FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Mac10.13-Clang-MacBookPro11.5-CPU-AVX2-x86_64-Debug-All-ASAN.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Ubuntu17-GCC-Golo-GPU-QuadroP400-x86_64-Release-All-Valgrind_AbandonGpuContext_SK_CPU_LIMIT_SSE41.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Win10-Clang-Golo-GPU-QuadroP400-x86_64-Release-All-Vulkan_ProcDump.json +FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/Test-Win10-MSVC-LenovoYogaC630-GPU-Adreno630-arm64-Debug-All-ANGLE.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/cpu_scale_failed.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/cpu_scale_failed_golo.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/cpu_scale_failed_once.json @@ -2387,6 +2056,7 @@ FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.e FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/retry_adb_command_retries_exhausted.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install_retries_exhausted.json +FILE: ../../../third_party/skia/infra/bots/recipe_modules/git/examples/full.expected/test-win.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/git/examples/full.expected/test.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/gsutil/examples/full.expected/failed_all_uploads.json FILE: ../../../third_party/skia/infra/bots/recipe_modules/gsutil/examples/full.expected/failed_one_upload.json @@ -2401,13 +2071,6 @@ FILE: ../../../third_party/skia/infra/bots/recipes/android_compile.expected/andr FILE: ../../../third_party/skia/infra/bots/recipes/android_compile.expected/android_compile_trybot.json FILE: ../../../third_party/skia/infra/bots/recipes/android_compile.expected/android_compile_trybot_failure.json FILE: ../../../third_party/skia/infra/bots/recipes/android_compile.expected/android_compile_unrecognized_target.json -FILE: ../../../third_party/skia/infra/bots/recipes/bookmaker.expected/nightly_bookmaker.json -FILE: ../../../third_party/skia/infra/bots/recipes/bookmaker.expected/nightly_failed_extract_fiddles.json -FILE: ../../../third_party/skia/infra/bots/recipes/bookmaker.expected/nightly_failed_fiddlecli.json -FILE: ../../../third_party/skia/infra/bots/recipes/bookmaker.expected/nightly_failed_fiddles.json -FILE: ../../../third_party/skia/infra/bots/recipes/bookmaker.expected/nightly_failed_upload.json -FILE: ../../../third_party/skia/infra/bots/recipes/bookmaker.expected/percommit_bookmaker.json -FILE: ../../../third_party/skia/infra/bots/recipes/bookmaker.expected/percommit_failed_validation.json FILE: ../../../third_party/skia/infra/bots/recipes/calmbench.expected/Calmbench-Debian9-Clang-GCE-CPU-AVX2-x86_64-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipes/calmbench.expected/Calmbench-Ubuntu17-Clang-Golo-GPU-QuadroP400-x86_64-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipes/check_generated_files.expected/Housekeeper-PerCommit-CheckGeneratedFiles.json @@ -2423,8 +2086,10 @@ FILE: ../../../third_party/skia/infra/bots/recipes/compute_test.expected/Test-De FILE: ../../../third_party/skia/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit-Trybot.json FILE: ../../../third_party/skia/infra/bots/recipes/housekeeper.expected/Housekeeper-PerCommit.json FILE: ../../../third_party/skia/infra/bots/recipes/infra.expected/infra_tests.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Release-All-Android.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Android-Clang-Nexus5-GPU-Adreno330-arm-Debug-All-Android.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Android-Clang-Nexus5x-GPU-Adreno418-arm64-Release-All-Android_NoGPUThreads.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Android-Clang-Nexus7-CPU-Tegra3-arm-Debug-All-Android.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-ChromeOS-Clang-ASUSChromebookFlipC100-GPU-MaliT764-arm-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Chromecast-Clang-Chorizo-CPU-Cortex_A7-arm-Debug-All.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Chromecast-Clang-Chorizo-GPU-Cortex_A7-arm-Release-All.json @@ -2433,12 +2098,13 @@ FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Debian9-Cl FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Debian9-Clang-GCE-CPU-AVX2-x86_64-Release-All-BonusConfigs.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Debian9-Clang-NUC5PPYH-GPU-IntelHD405-x86_64-Debug-All-Vulkan.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Release-All.json -FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Mac-Clang-MacBook10.1-GPU-IntelHD615-x86_64-Release-All-CommandBuffer.json -FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Mac-Clang-MacBookPro11.5-GPU-RadeonHD8870M-x86_64-Release-All-MoltenVK_Vulkan.json -FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Mac-Clang-MacMini7.1-GPU-IntelIris5100-x86_64-Release-All-CommandBuffer.json -FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Ubuntu17-GCC-Golo-GPU-QuadroP400-x86_64-Release-All-Valgrind_AbandonGpuContext_SK_CPU_LIMIT_SSE41.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Mac10.13-Clang-MacBook10.1-GPU-IntelHD615-x86_64-Release-All-CommandBuffer.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Mac10.13-Clang-MacBookPro11.5-GPU-RadeonHD8870M-x86_64-Release-All-MoltenVK_Vulkan.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Mac10.13-Clang-MacMini7.1-GPU-IntelIris5100-x86_64-Release-All-CommandBuffer.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Ubuntu17-GCC-Golo-GPU-QuadroP400-x86_64-Release-All-Valgrind_SK_CPU_LIMIT_SSE41.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Win10-Clang-Golo-GPU-QuadroP400-x86_64-Release-All-ANGLE.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Win10-Clang-NUC8i5BEK-GPU-IntelIris655-x86_64-Release-All-Vulkan.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-Win10-Clang-NUC8i5BEK-GPU-IntelIris655-x86_64-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipes/perf.expected/trybot.json FILE: ../../../third_party/skia/infra/bots/recipes/perf_canvaskit.expected/Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-CanvasKit.json @@ -2446,6 +2112,10 @@ FILE: ../../../third_party/skia/infra/bots/recipes/perf_canvaskit.expected/pathk FILE: ../../../third_party/skia/infra/bots/recipes/perf_pathkit.expected/Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit.json FILE: ../../../third_party/skia/infra/bots/recipes/perf_pathkit.expected/Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit.json FILE: ../../../third_party/skia/infra/bots/recipes/perf_pathkit.expected/pathkit_trybot.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf_skottietrace.expected/Perf-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-All-Android_SkottieTracing.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf_skottietrace.expected/Perf-Debian9-Clang-GCE-CPU-AVX2-x86_64-Release-All-SkottieTracing.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf_skottietrace.expected/skottietracing_parse_trace_error.json +FILE: ../../../third_party/skia/infra/bots/recipes/perf_skottietrace.expected/skottietracing_trybot.json FILE: ../../../third_party/skia/infra/bots/recipes/recreate_skps.expected/Housekeeper-Nightly-RecreateSKPs_Canary.json FILE: ../../../third_party/skia/infra/bots/recipes/recreate_skps.expected/Housekeeper-Weekly-RecreateSKPs.json FILE: ../../../third_party/skia/infra/bots/recipes/recreate_skps.expected/failed_upload.json @@ -2466,6 +2136,7 @@ FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Android-Cl FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Android-Clang-NexusPlayer-GPU-PowerVRG6430-x86-Release-All-Android.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Android-Clang-Pixel-GPU-Adreno530-arm-Debug-All-Android_ASAN.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Android-Clang-Pixel-GPU-Adreno530-arm64-Debug-All-Android_Vulkan.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Android-Clang-Pixel3-GPU-Adreno630-arm64-Debug-All-Android_Vulkan.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-ChromeOS-Clang-AcerChromebookR13Convertible-GPU-PowerVRGX6250-arm-Debug-All.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Chromecast-Clang-Chorizo-CPU-Cortex_A7-arm-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Chromecast-Clang-Chorizo-GPU-Cortex_A7-arm-Release-All.json @@ -2473,6 +2144,7 @@ FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Cl FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-GCE-CPU-AVX2-x86_64-Debug-All-BonusConfigs.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-GCE-CPU-AVX2-x86_64-Debug-All-MSAN.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-GCE-CPU-AVX2-x86_64-Debug-All-SK_USE_DISCARDABLE_SCALEDIMAGECACHE.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-GCE-CPU-AVX2-x86_64-Debug-All-Wuffs.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-GCE-CPU-AVX2-x86_64-Debug-shard_00_10-Coverage.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-GCE-CPU-AVX2-x86_64-Release-All-Lottie.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-GCE-CPU-AVX2-x86_64-Release-All-SK_FORCE_RASTER_PIPELINE_BLITTER.json @@ -2480,12 +2152,12 @@ FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Cl FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-GCE-GPU-SwiftShader-x86_64-Release-All-SwiftShader.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-NUC5PPYH-GPU-IntelHD405-x86_64-Release-All-Vulkan.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All-Vulkan.json -FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac-Clang-MacBook10.1-GPU-IntelHD615-x86_64-Release-All-NativeFonts.json -FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac-Clang-MacBookAir7.2-GPU-IntelHD6000-x86_64-Debug-All.json -FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac-Clang-MacBookPro11.5-CPU-AVX2-x86_64-Release-All.json -FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac-Clang-MacBookPro11.5-GPU-RadeonHD8870M-x86_64-Debug-All-Metal.json -FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac-Clang-MacBookPro11.5-GPU-RadeonHD8870M-x86_64-Release-All-MoltenVK_Vulkan.json -FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac-Clang-MacMini7.1-GPU-IntelIris5100-x86_64-Debug-All-CommandBuffer.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac10.13-Clang-MacBook10.1-GPU-IntelHD615-x86_64-Release-All-NativeFonts.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac10.13-Clang-MacBookPro11.5-CPU-AVX2-x86_64-Release-All.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac10.13-Clang-MacBookPro11.5-GPU-RadeonHD8870M-x86_64-Debug-All-Metal.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac10.13-Clang-MacBookPro11.5-GPU-RadeonHD8870M-x86_64-Release-All-MoltenVK_Vulkan.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac10.13-Clang-MacMini7.1-GPU-IntelIris5100-x86_64-Debug-All-CommandBuffer.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Mac10.14-Clang-MacBookAir7.2-GPU-IntelHD6000-x86_64-Debug-All.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Ubuntu17-Clang-Golo-GPU-QuadroP400-x86_64-Debug-All-DDL1.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Ubuntu17-Clang-Golo-GPU-QuadroP400-x86_64-Debug-All-DDL3.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Ubuntu17-Clang-Golo-GPU-QuadroP400-x86_64-Debug-All-Lottie.json @@ -2500,9 +2172,10 @@ FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win10-Clan FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win10-Clang-NUCD34010WYKH-GPU-IntelHD4400-x86_64-Release-All-ANGLE.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win10-Clang-ShuttleA-GPU-GTX660-x86_64-Release-All-Vulkan.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win10-Clang-ShuttleC-GPU-GTX960-x86_64-Debug-All-ANGLE.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win10-MSVC-LenovoYogaC630-GPU-Adreno630-arm64-Debug-All-ANGLE.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win2016-Clang-GCE-CPU-AVX2-x86_64-Debug-All-FAAA.json -FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win2016-Clang-GCE-CPU-AVX2-x86_64-Debug-All-FDAA.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win2016-Clang-GCE-CPU-AVX2-x86_64-Debug-All-FSAA.json +FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-Win2016-MSVC-GCE-CPU-AVX2-x86_64-Debug-All-MSRTC.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/Test-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/failed_dm.json FILE: ../../../third_party/skia/infra/bots/recipes/test.expected/failed_get_hashes.json @@ -2520,7 +2193,6 @@ FILE: ../../../third_party/skia/infra/bots/recipes/test_pathkit.expected/Test-De FILE: ../../../third_party/skia/infra/bots/recipes/test_pathkit.expected/Test-Debian9-EMCC-GCE-CPU-AVX2-wasm-Debug-All-PathKit.json FILE: ../../../third_party/skia/infra/bots/recipes/test_pathkit.expected/pathkit_trybot.json FILE: ../../../third_party/skia/infra/bots/recipes/test_skqp_emulator.expected/Test-Debian9-Clang-GCE-CPU-Emulator-x86-devrel-All-Android_SKQP.json -FILE: ../../../third_party/skia/infra/bots/recipes/update_go_deps.expected/Housekeeper-Nightly-UpdateGoDEPS.json FILE: ../../../third_party/skia/infra/bots/recipes/upload_buildstats_results.expected/normal_bot.json FILE: ../../../third_party/skia/infra/bots/recipes/upload_buildstats_results.expected/trybot.json FILE: ../../../third_party/skia/infra/bots/recipes/upload_calmbench_results.expected/normal_bot.json @@ -2542,19 +2214,61 @@ FILE: ../../../third_party/skia/infra/bots/test_skia_bundled.isolate FILE: ../../../third_party/skia/infra/bots/tools/luci-go/linux64/isolate.sha1 FILE: ../../../third_party/skia/infra/bots/tools/luci-go/mac64/isolate.sha1 FILE: ../../../third_party/skia/infra/bots/tools/luci-go/win64/isolate.exe.sha1 -FILE: ../../../third_party/skia/infra/branch-config/cq.cfg +FILE: ../../../third_party/skia/infra/canvaskit/docker/canvaskit-emsdk/Dockerfile FILE: ../../../third_party/skia/infra/config/recipes.cfg +FILE: ../../../third_party/skia/infra/cross-compile/docker/cross-linux-arm64/Dockerfile FILE: ../../../third_party/skia/infra/cts/whitelist_devices.json FILE: ../../../third_party/skia/infra/lottiecap/docker/gold-lottie-web-puppeteer/Dockerfile FILE: ../../../third_party/skia/infra/lottiecap/docker/lottie-web-puppeteer/Dockerfile -FILE: ../../../third_party/skia/infra/pathkit/docker/emsdk-base/Dockerfile -FILE: ../../../third_party/skia/infra/pathkit/docker/gold-karma-chrome-tests/Dockerfile -FILE: ../../../third_party/skia/infra/pathkit/docker/karma-chrome-tests/Dockerfile -FILE: ../../../third_party/skia/infra/pathkit/docker/perf-karma-chrome-tests/Dockerfile FILE: ../../../third_party/skia/infra/project-config/cr-buildbucket.cfg FILE: ../../../third_party/skia/infra/project-config/project.cfg FILE: ../../../third_party/skia/infra/project-config/refs.cfg FILE: ../../../third_party/skia/infra/skqp/docker/android-skqp/Dockerfile +FILE: ../../../third_party/skia/infra/wasm-common/docker/emsdk-base/Dockerfile +FILE: ../../../third_party/skia/infra/wasm-common/docker/gold-karma-chrome-tests/Dockerfile +FILE: ../../../third_party/skia/infra/wasm-common/docker/karma-chrome-tests/Dockerfile +FILE: ../../../third_party/skia/infra/wasm-common/docker/perf-karma-chrome-tests/Dockerfile +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit/NotoSerif-Regular.ttf +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit/Roboto-Regular.ttf +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit/Roboto-Regular.woff +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit/example.html +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit/extra.html +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit/node.example.js +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit/package.json +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit/test.png +FILE: ../../../third_party/skia/modules/canvaskit/cpu.js +FILE: ../../../third_party/skia/modules/canvaskit/debug.js +FILE: ../../../third_party/skia/modules/canvaskit/externs.js +FILE: ../../../third_party/skia/modules/canvaskit/fonts/NotoMono-Regular.ttf +FILE: ../../../third_party/skia/modules/canvaskit/gpu.js +FILE: ../../../third_party/skia/modules/canvaskit/helper.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/_namedcolors.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/canvas2dcontext.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/color.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/font.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/htmlcanvas.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/imagedata.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/lineargradient.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/path2d.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/pattern.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/postamble.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/preamble.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/radialgradient.js +FILE: ../../../third_party/skia/modules/canvaskit/htmlcanvas/util.js +FILE: ../../../third_party/skia/modules/canvaskit/interface.js +FILE: ../../../third_party/skia/modules/canvaskit/karma.bench.conf.js +FILE: ../../../third_party/skia/modules/canvaskit/karma.conf.js +FILE: ../../../third_party/skia/modules/canvaskit/package.json +FILE: ../../../third_party/skia/modules/canvaskit/perf/animation.bench.js +FILE: ../../../third_party/skia/modules/canvaskit/perf/assets/confetti.json +FILE: ../../../third_party/skia/modules/canvaskit/perf/assets/drinks.json +FILE: ../../../third_party/skia/modules/canvaskit/perf/assets/lego_loader.json +FILE: ../../../third_party/skia/modules/canvaskit/perf/assets/onboarding.json +FILE: ../../../third_party/skia/modules/canvaskit/postamble.js +FILE: ../../../third_party/skia/modules/canvaskit/preamble.js +FILE: ../../../third_party/skia/modules/canvaskit/ready.js +FILE: ../../../third_party/skia/modules/canvaskit/release.js +FILE: ../../../third_party/skia/modules/canvaskit/skottie.js FILE: ../../../third_party/skia/modules/pathkit/chaining.js FILE: ../../../third_party/skia/modules/pathkit/externs.js FILE: ../../../third_party/skia/modules/pathkit/helper.js @@ -2627,233 +2341,17 @@ FILE: ../../../third_party/skia/site/user/api/METADATA FILE: ../../../third_party/skia/site/user/api/catalog.htm FILE: ../../../third_party/skia/site/user/modules/METADATA FILE: ../../../third_party/skia/site/user/modules/PathKit_effects.png -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_kernels.bin -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_kernels.bin.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_kernels.bin.xxd -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_kernels.pre.cl -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_kernels.src.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u32/hs_kernels.src.xxd -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_kernels.bin -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_kernels.bin.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_kernels.bin.xxd -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_kernels.pre.cl -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_kernels.src.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/cl/intel/gen8/u64/hs_kernels.src.xxd -FILE: ../../../third_party/skia/src/compute/hs/images/hs_amd_gcn_mkeys.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_amd_gcn_msecs.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_flip_merge.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_intel_gen8_mkeys.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_intel_gen8_msecs.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_nvidia_sm35_u32_mkeys.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_nvidia_sm35_u32_msecs.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_nvidia_sm35_u64_mkeys.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_nvidia_sm35_u64_msecs.svg -FILE: ../../../third_party/skia/src/compute/hs/images/hs_sorted_slab.svg -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bc_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_bs_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_fm_1_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_hm_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_hm_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_transpose.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u32/hs_transpose.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bc_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_bs_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_fm_1_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_hm_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_hm_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_transpose.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/amd/gcn/u64/hs_transpose.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bc_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_bs_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_fm_0_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_fm_0_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_fm_0_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_fm_0_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_fm_0_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_fm_0_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_fm_0_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_fm_0_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_hm_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_hm_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_transpose.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u32/hs_transpose.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bc_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_bs_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_fm_1_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_hm_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_hm_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_transpose.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/intel/gen8/u64/hs_transpose.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bc_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_bs_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_fm_0_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_fm_0_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_fm_0_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_fm_0_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_fm_0_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_fm_0_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_fm_0_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_fm_0_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_hm_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_hm_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_transpose.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u32/hs_transpose.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bc_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_4.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_bs_4.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_fm_0_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_fm_0_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_fm_0_1.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_fm_0_1.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_fm_0_2.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_fm_0_2.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_fm_0_3.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_fm_0_3.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_hm_0.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_hm_0.spv.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_transpose.len.xxd -FILE: ../../../third_party/skia/src/compute/hs/vk/nvidia/sm_35/u64/hs_transpose.spv.xxd +FILE: ../../../third_party/skia/specs/web-img-decode/current/index.html +FILE: ../../../third_party/skia/specs/web-img-decode/proposed/impl/impl.js +FILE: ../../../third_party/skia/specs/web-img-decode/proposed/index.html FILE: ../../../third_party/skia/src/core/SkOrderedReadBuffer.h FILE: ../../../third_party/skia/src/sksl/lex/sksl.lex FILE: ../../../third_party/skia/src/sksl/sksl.inc FILE: ../../../third_party/skia/src/sksl/sksl_fp.inc FILE: ../../../third_party/skia/src/sksl/sksl_frag.inc +FILE: ../../../third_party/skia/src/sksl/sksl_generic.inc FILE: ../../../third_party/skia/src/sksl/sksl_geom.inc -FILE: ../../../third_party/skia/src/sksl/sksl_pipeline.inc +FILE: ../../../third_party/skia/src/sksl/sksl_mixer.inc FILE: ../../../third_party/skia/src/sksl/sksl_vert.inc ---------------------------------------------------------------------------------------------------- Copyright (c) 2011 Google Inc. All rights reserved. @@ -2973,7 +2471,6 @@ FILE: ../../../third_party/skia/include/core/SkImageEncoder.h FILE: ../../../third_party/skia/include/core/SkImageFilter.h FILE: ../../../third_party/skia/include/core/SkMatrix44.h FILE: ../../../third_party/skia/include/core/SkSize.h -FILE: ../../../third_party/skia/include/core/SkTLazy.h FILE: ../../../third_party/skia/include/effects/SkLayerDrawLooper.h FILE: ../../../third_party/skia/include/gpu/GrRenderTarget.h FILE: ../../../third_party/skia/include/gpu/GrTexture.h @@ -2996,19 +2493,16 @@ FILE: ../../../third_party/skia/samplecode/SampleBigGradient.cpp FILE: ../../../third_party/skia/samplecode/SampleBitmapRect.cpp FILE: ../../../third_party/skia/samplecode/SampleCamera.cpp FILE: ../../../third_party/skia/samplecode/SampleCircle.cpp -FILE: ../../../third_party/skia/samplecode/SampleClamp.cpp FILE: ../../../third_party/skia/samplecode/SampleClip.cpp FILE: ../../../third_party/skia/samplecode/SampleColorFilter.cpp FILE: ../../../third_party/skia/samplecode/SampleComplexClip.cpp FILE: ../../../third_party/skia/samplecode/SampleConcavePaths.cpp -FILE: ../../../third_party/skia/samplecode/SampleDash.cpp FILE: ../../../third_party/skia/samplecode/SampleDegenerateTwoPtRadials.cpp FILE: ../../../third_party/skia/samplecode/SampleEffects.cpp FILE: ../../../third_party/skia/samplecode/SampleEmboss.cpp FILE: ../../../third_party/skia/samplecode/SampleFillType.cpp FILE: ../../../third_party/skia/samplecode/SampleFilter2.cpp FILE: ../../../third_party/skia/samplecode/SampleFontCache.cpp -FILE: ../../../third_party/skia/samplecode/SampleFuzz.cpp FILE: ../../../third_party/skia/samplecode/SampleGradients.cpp FILE: ../../../third_party/skia/samplecode/SampleHairCurves.cpp FILE: ../../../third_party/skia/samplecode/SampleHairModes.cpp @@ -3021,7 +2515,6 @@ FILE: ../../../third_party/skia/samplecode/SamplePatch.cpp FILE: ../../../third_party/skia/samplecode/SamplePath.cpp FILE: ../../../third_party/skia/samplecode/SamplePathClip.cpp FILE: ../../../third_party/skia/samplecode/SamplePathEffects.cpp -FILE: ../../../third_party/skia/samplecode/SamplePathFill.cpp FILE: ../../../third_party/skia/samplecode/SamplePoints.cpp FILE: ../../../third_party/skia/samplecode/SamplePolyToPoly.cpp FILE: ../../../third_party/skia/samplecode/SampleRegion.cpp @@ -3046,7 +2539,7 @@ FILE: ../../../third_party/skia/src/core/SkBlitRow.h FILE: ../../../third_party/skia/src/core/SkBlitRow_D32.cpp FILE: ../../../third_party/skia/src/core/SkClipStack.cpp FILE: ../../../third_party/skia/src/core/SkClipStack.h -FILE: ../../../third_party/skia/src/core/SkColorMatrixFilterRowMajor255.cpp +FILE: ../../../third_party/skia/src/core/SkColorFilter_Matrix.cpp FILE: ../../../third_party/skia/src/core/SkConvertPixels.h FILE: ../../../third_party/skia/src/core/SkData.cpp FILE: ../../../third_party/skia/src/core/SkDevice.cpp @@ -3068,6 +2561,7 @@ FILE: ../../../third_party/skia/src/core/SkPictureRecord.h FILE: ../../../third_party/skia/src/core/SkPixelRef.cpp FILE: ../../../third_party/skia/src/core/SkPtrRecorder.cpp FILE: ../../../third_party/skia/src/core/SkReadBuffer.h +FILE: ../../../third_party/skia/src/core/SkTLazy.h FILE: ../../../third_party/skia/src/core/SkTypefaceCache.cpp FILE: ../../../third_party/skia/src/core/SkTypefaceCache.h FILE: ../../../third_party/skia/src/core/SkUnPreMultiply.cpp @@ -3094,7 +2588,6 @@ FILE: ../../../third_party/skia/src/gpu/GrStencilAttachment.h FILE: ../../../third_party/skia/src/gpu/GrStencilSettings.cpp FILE: ../../../third_party/skia/src/gpu/GrTexture.cpp FILE: ../../../third_party/skia/src/gpu/SkGpuDevice.cpp -FILE: ../../../third_party/skia/src/gpu/gl/GrGLCreateNullInterface.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLDefines.h FILE: ../../../third_party/skia/src/gpu/gl/GrGLGLSL.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLGLSL.h @@ -3102,7 +2595,7 @@ FILE: ../../../third_party/skia/src/gpu/gl/GrGLGpu.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLGpu.h FILE: ../../../third_party/skia/src/gpu/gl/GrGLGpuProgramCache.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLIRect.h -FILE: ../../../third_party/skia/src/gpu/gl/GrGLInterface.cpp +FILE: ../../../third_party/skia/src/gpu/gl/GrGLInterfaceAutogen.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLMakeNativeInterface_none.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLProgram.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLProgram.h @@ -3121,7 +2614,6 @@ FILE: ../../../third_party/skia/src/gpu/ops/GrAAHairLinePathRenderer.cpp FILE: ../../../third_party/skia/src/gpu/ops/GrAAHairLinePathRenderer.h FILE: ../../../third_party/skia/src/gpu/ops/GrDefaultPathRenderer.cpp FILE: ../../../third_party/skia/src/gpu/ops/GrDefaultPathRenderer.h -FILE: ../../../third_party/skia/src/pdf/SkPDFConvertType1FontStream.cpp FILE: ../../../third_party/skia/src/pdf/SkPDFDevice.cpp FILE: ../../../third_party/skia/src/pdf/SkPDFDevice.h FILE: ../../../third_party/skia/src/pdf/SkPDFDocument.cpp @@ -3331,8 +2823,6 @@ FILE: ../../../third_party/skia/src/gpu/GrRectanizer_pow2.h FILE: ../../../third_party/skia/src/gpu/GrRectanizer_skyline.h FILE: ../../../third_party/skia/src/gpu/GrResourceCache.cpp FILE: ../../../third_party/skia/src/gpu/GrResourceCache.h -FILE: ../../../third_party/skia/src/gpu/GrSKSLPrettyPrint.cpp -FILE: ../../../third_party/skia/src/gpu/GrSKSLPrettyPrint.h FILE: ../../../third_party/skia/src/gpu/GrSurfacePriv.h FILE: ../../../third_party/skia/src/gpu/GrTRecorder.h FILE: ../../../third_party/skia/src/gpu/GrTexturePriv.h @@ -3754,7 +3244,6 @@ FILE: ../../../third_party/skia/include/codec/SkAndroidCodec.h FILE: ../../../third_party/skia/include/codec/SkCodec.h FILE: ../../../third_party/skia/include/core/SkEncodedImageFormat.h FILE: ../../../third_party/skia/include/core/SkFilterQuality.h -FILE: ../../../third_party/skia/include/core/SkLights.h FILE: ../../../third_party/skia/include/core/SkPixmap.h FILE: ../../../third_party/skia/include/core/SkPngChunkReader.h FILE: ../../../third_party/skia/include/core/SkPoint3.h @@ -3787,7 +3276,6 @@ FILE: ../../../third_party/skia/samplecode/SampleAtlas.cpp FILE: ../../../third_party/skia/samplecode/SampleClipDrawMatch.cpp FILE: ../../../third_party/skia/samplecode/SampleFilterQuality.cpp FILE: ../../../third_party/skia/samplecode/SampleLighting.cpp -FILE: ../../../third_party/skia/samplecode/SamplePathFuzz.cpp FILE: ../../../third_party/skia/samplecode/SampleShip.cpp FILE: ../../../third_party/skia/samplecode/SampleXfer.cpp FILE: ../../../third_party/skia/src/android/SkBitmapRegionCodec.cpp @@ -3844,13 +3332,10 @@ FILE: ../../../third_party/skia/src/core/SkBitmapController.cpp FILE: ../../../third_party/skia/src/core/SkBitmapController.h FILE: ../../../third_party/skia/src/core/SkBitmapProvider.cpp FILE: ../../../third_party/skia/src/core/SkBitmapProvider.h -FILE: ../../../third_party/skia/src/core/SkFindAndPlaceGlyph.h FILE: ../../../third_party/skia/src/core/SkFontMgr.cpp FILE: ../../../third_party/skia/src/core/SkLatticeIter.cpp FILE: ../../../third_party/skia/src/core/SkLatticeIter.h FILE: ../../../third_party/skia/src/core/SkLocalMatrixImageFilter.cpp -FILE: ../../../third_party/skia/src/core/SkMiniRecorder.cpp -FILE: ../../../third_party/skia/src/core/SkMiniRecorder.h FILE: ../../../third_party/skia/src/core/SkNextID.h FILE: ../../../third_party/skia/src/core/SkOpts.cpp FILE: ../../../third_party/skia/src/core/SkOpts.h @@ -4041,6 +3526,7 @@ FILE: ../../../third_party/skia/src/shaders/SkImageShader.cpp FILE: ../../../third_party/skia/src/shaders/SkImageShader.h FILE: ../../../third_party/skia/src/shaders/SkLightingShader.cpp FILE: ../../../third_party/skia/src/shaders/SkLightingShader.h +FILE: ../../../third_party/skia/src/shaders/SkLights.h FILE: ../../../third_party/skia/src/svg/SkSVGCanvas.cpp FILE: ../../../third_party/skia/src/svg/SkSVGDevice.cpp FILE: ../../../third_party/skia/src/svg/SkSVGDevice.h @@ -4126,14 +3612,14 @@ FILE: ../../../third_party/skia/gm/circularclips.cpp FILE: ../../../third_party/skia/gm/clippedbitmapshaders.cpp FILE: ../../../third_party/skia/gm/coloremoji.cpp FILE: ../../../third_party/skia/gm/conicpaths.cpp -FILE: ../../../third_party/skia/gm/copyTo4444.cpp +FILE: ../../../third_party/skia/gm/copy_to_4444.cpp FILE: ../../../third_party/skia/gm/displacement.cpp FILE: ../../../third_party/skia/gm/downsamplebitmap.cpp FILE: ../../../third_party/skia/gm/dropshadowimagefilter.cpp FILE: ../../../third_party/skia/gm/dstreadshuffle.cpp FILE: ../../../third_party/skia/gm/fontcache.cpp FILE: ../../../third_party/skia/gm/fontmgr.cpp -FILE: ../../../third_party/skia/gm/gradientDirtyLaundry.cpp +FILE: ../../../third_party/skia/gm/gradient_dirty_laundry.cpp FILE: ../../../third_party/skia/gm/gradient_matrix.cpp FILE: ../../../third_party/skia/gm/gradients_no_texture.cpp FILE: ../../../third_party/skia/gm/hairlines.cpp @@ -4186,7 +3672,6 @@ FILE: ../../../third_party/skia/include/gpu/GrBlend.h FILE: ../../../third_party/skia/include/gpu/gl/GrGLExtensions.h FILE: ../../../third_party/skia/include/ports/SkFontConfigInterface.h FILE: ../../../third_party/skia/include/private/GrTypesPriv.h -FILE: ../../../third_party/skia/include/private/SkMessageBus.h FILE: ../../../third_party/skia/include/private/SkOnce.h FILE: ../../../third_party/skia/include/private/SkTFitsIn.h FILE: ../../../third_party/skia/include/private/SkTLogic.h @@ -4211,6 +3696,7 @@ FILE: ../../../third_party/skia/src/core/SkFontStream.h FILE: ../../../third_party/skia/src/core/SkGpuBlurUtils.cpp FILE: ../../../third_party/skia/src/core/SkGpuBlurUtils.h FILE: ../../../third_party/skia/src/core/SkMatrixUtils.h +FILE: ../../../third_party/skia/src/core/SkMessageBus.h FILE: ../../../third_party/skia/src/core/SkMipMap.cpp FILE: ../../../third_party/skia/src/core/SkMipMap.h FILE: ../../../third_party/skia/src/core/SkPaintPriv.cpp @@ -4320,8 +3806,6 @@ ORIGIN: ../../../third_party/skia/bench/ClipMaskBench.cpp + ../../../third_party TYPE: LicenseType.bsd FILE: ../../../third_party/skia/bench/ClipMaskBench.cpp FILE: ../../../third_party/skia/bench/ClipStrategyBench.cpp -FILE: ../../../third_party/skia/bench/ColorCanvasDrawBitmapBench.cpp -FILE: ../../../third_party/skia/bench/ColorSpaceXformBench.cpp FILE: ../../../third_party/skia/bench/CubicKLMBench.cpp FILE: ../../../third_party/skia/bench/PathTextBench.cpp FILE: ../../../third_party/skia/bench/ShadowBench.cpp @@ -4354,7 +3838,7 @@ FILE: ../../../third_party/skia/gm/crbug_788500.cpp FILE: ../../../third_party/skia/gm/crosscontextimage.cpp FILE: ../../../third_party/skia/gm/dftext_blob_persp.cpp FILE: ../../../third_party/skia/gm/drrect_small_inner.cpp -FILE: ../../../third_party/skia/gm/encode-alpha-jpeg.cpp +FILE: ../../../third_party/skia/gm/encode_alpha_jpeg.cpp FILE: ../../../third_party/skia/gm/etc1.cpp FILE: ../../../third_party/skia/gm/flippity.cpp FILE: ../../../third_party/skia/gm/highcontrastfilter.cpp @@ -4368,20 +3852,17 @@ FILE: ../../../third_party/skia/gm/pictureshadercache.cpp FILE: ../../../third_party/skia/gm/radial_gradient_precision.cpp FILE: ../../../third_party/skia/gm/savelayer.cpp FILE: ../../../third_party/skia/gm/shadowutils.cpp -FILE: ../../../third_party/skia/gm/shapes_as_paths.cpp FILE: ../../../third_party/skia/gm/simple_magnification.cpp FILE: ../../../third_party/skia/gm/srgb.cpp FILE: ../../../third_party/skia/gm/testgradient.cpp FILE: ../../../third_party/skia/gm/text_scale_skew.cpp FILE: ../../../third_party/skia/gm/thinconcavepaths.cpp -FILE: ../../../third_party/skia/gm/tosrgb_colorfilter.cpp FILE: ../../../third_party/skia/include/android/SkAndroidFrameworkUtils.h FILE: ../../../third_party/skia/include/atlastext/SkAtlasTextContext.h FILE: ../../../third_party/skia/include/atlastext/SkAtlasTextFont.h FILE: ../../../third_party/skia/include/atlastext/SkAtlasTextRenderer.h FILE: ../../../third_party/skia/include/atlastext/SkAtlasTextTarget.h FILE: ../../../third_party/skia/include/codec/SkEncodedOrigin.h -FILE: ../../../third_party/skia/include/core/SkColorSpaceXformCanvas.h FILE: ../../../third_party/skia/include/core/SkDeferredDisplayListRecorder.h FILE: ../../../third_party/skia/include/core/SkExecutor.h FILE: ../../../third_party/skia/include/core/SkFontArguments.h @@ -4391,7 +3872,6 @@ FILE: ../../../third_party/skia/include/core/SkSurfaceCharacterization.h FILE: ../../../third_party/skia/include/core/SkVertices.h FILE: ../../../third_party/skia/include/docs/SkXPSDocument.h FILE: ../../../third_party/skia/include/effects/SkHighContrastFilter.h -FILE: ../../../third_party/skia/include/effects/SkToSRGBColorFilter.h FILE: ../../../third_party/skia/include/encode/SkEncoder.h FILE: ../../../third_party/skia/include/encode/SkJpegEncoder.h FILE: ../../../third_party/skia/include/encode/SkPngEncoder.h @@ -4412,7 +3892,6 @@ FILE: ../../../third_party/skia/modules/skottie/src/Skottie.cpp FILE: ../../../third_party/skia/modules/skottie/src/SkottieAnimator.cpp FILE: ../../../third_party/skia/modules/skottie/src/SkottieValue.cpp FILE: ../../../third_party/skia/modules/skottie/src/SkottieValue.h -FILE: ../../../third_party/skia/modules/sksg/include/SkSGColor.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGDraw.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGEffectNode.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGGeometryNode.h @@ -4420,13 +3899,12 @@ FILE: ../../../third_party/skia/modules/sksg/include/SkSGGroup.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGInvalidationController.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGMerge.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGNode.h -FILE: ../../../third_party/skia/modules/sksg/include/SkSGPaintNode.h +FILE: ../../../third_party/skia/modules/sksg/include/SkSGPaint.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGPath.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGRect.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGRenderNode.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGTransform.h FILE: ../../../third_party/skia/modules/sksg/include/SkSGTrimEffect.h -FILE: ../../../third_party/skia/modules/sksg/src/SkSGColor.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGDraw.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGEffectNode.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGGeometryNode.cpp @@ -4434,7 +3912,7 @@ FILE: ../../../third_party/skia/modules/sksg/src/SkSGGroup.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGInvalidationController.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGMerge.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGNode.cpp -FILE: ../../../third_party/skia/modules/sksg/src/SkSGPaintNode.cpp +FILE: ../../../third_party/skia/modules/sksg/src/SkSGPaint.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGPath.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGRect.cpp FILE: ../../../third_party/skia/modules/sksg/src/SkSGRenderNode.cpp @@ -4443,6 +3921,7 @@ FILE: ../../../third_party/skia/modules/sksg/src/SkSGTrimEffect.cpp FILE: ../../../third_party/skia/samplecode/SampleCCPRGeometry.cpp FILE: ../../../third_party/skia/samplecode/SampleChineseFling.cpp FILE: ../../../third_party/skia/samplecode/SampleCowboy.cpp +FILE: ../../../third_party/skia/samplecode/SampleMixer.cpp FILE: ../../../third_party/skia/samplecode/SamplePathText.cpp FILE: ../../../third_party/skia/samplecode/SampleShadowColor.cpp FILE: ../../../third_party/skia/samplecode/SampleShadowReference.cpp @@ -4461,87 +3940,12 @@ FILE: ../../../third_party/skia/src/codec/SkHeifCodec.h FILE: ../../../third_party/skia/src/codec/SkJpegPriv.h FILE: ../../../third_party/skia/src/codec/SkPngPriv.h FILE: ../../../third_party/skia/src/codec/SkStubHeifDecoderAPI.h -FILE: ../../../third_party/skia/src/compute/color/color.c -FILE: ../../../third_party/skia/src/compute/color/color.h -FILE: ../../../third_party/skia/src/compute/skc/assert_state.h -FILE: ../../../third_party/skia/src/compute/skc/block.h -FILE: ../../../third_party/skia/src/compute/skc/common.h -FILE: ../../../third_party/skia/src/compute/skc/composition.c -FILE: ../../../third_party/skia/src/compute/skc/composition.h -FILE: ../../../third_party/skia/src/compute/skc/context.c -FILE: ../../../third_party/skia/src/compute/skc/context.h -FILE: ../../../third_party/skia/src/compute/skc/extent_ring.c -FILE: ../../../third_party/skia/src/compute/skc/extent_ring.h -FILE: ../../../third_party/skia/src/compute/skc/grid.c -FILE: ../../../third_party/skia/src/compute/skc/grid.h -FILE: ../../../third_party/skia/src/compute/skc/handle.h -FILE: ../../../third_party/skia/src/compute/skc/macros.h -FILE: ../../../third_party/skia/src/compute/skc/main.c -FILE: ../../../third_party/skia/src/compute/skc/path.h -FILE: ../../../third_party/skia/src/compute/skc/path_builder.c -FILE: ../../../third_party/skia/src/compute/skc/path_builder.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/atomic_cl.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/block_pool_cl.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/block_pool_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/composition_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/composition_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/config_cl.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/cq_pool_cl.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/cq_pool_cl.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/device_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/export_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/extent_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/extent_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/extent_cl_12_unified.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/handle_pool_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/handle_pool_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/block_pool_init.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/devices/avx2/device_cl_12_avx2.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/devices/gen9/device_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/devices/gen9/kernel_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/fills_expand.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/paths_copy.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/paths_reclaim.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/place.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/prefix.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/rasterize.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/rasters_alloc.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/kernels/rasters_reclaim.cl -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/path_builder_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/path_builder_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/raster_builder_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/raster_builder_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/runtime_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/runtime_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/skc_cl.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/styling_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/styling_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/surface_cl_12.c -FILE: ../../../third_party/skia/src/compute/skc/platforms/cl_12/surface_cl_12.h -FILE: ../../../third_party/skia/src/compute/skc/raster.h -FILE: ../../../third_party/skia/src/compute/skc/raster_builder.c -FILE: ../../../third_party/skia/src/compute/skc/raster_builder.h -FILE: ../../../third_party/skia/src/compute/skc/scheduler.cpp -FILE: ../../../third_party/skia/src/compute/skc/scheduler.h -FILE: ../../../third_party/skia/src/compute/skc/skc.h -FILE: ../../../third_party/skia/src/compute/skc/skc_styling.h -FILE: ../../../third_party/skia/src/compute/skc/subblock.h -FILE: ../../../third_party/skia/src/compute/skc/surface.c -FILE: ../../../third_party/skia/src/compute/skc/surface.h -FILE: ../../../third_party/skia/src/compute/skc/types.h -FILE: ../../../third_party/skia/src/compute/skc/weakref.c -FILE: ../../../third_party/skia/src/compute/skc/weakref.h FILE: ../../../third_party/skia/src/core/SkArenaAllocList.h FILE: ../../../third_party/skia/src/core/SkAutoBlitterChoose.h FILE: ../../../third_party/skia/src/core/SkBlendMode.cpp FILE: ../../../third_party/skia/src/core/SkBlitter_RGB565.cpp FILE: ../../../third_party/skia/src/core/SkClipStackDevice.cpp FILE: ../../../third_party/skia/src/core/SkClipStackDevice.h -FILE: ../../../third_party/skia/src/core/SkColorSpaceXformCanvas.cpp -FILE: ../../../third_party/skia/src/core/SkColorSpaceXformer.cpp -FILE: ../../../third_party/skia/src/core/SkColorSpaceXformer.h -FILE: ../../../third_party/skia/src/core/SkCoverageDelta.cpp -FILE: ../../../third_party/skia/src/core/SkCoverageDelta.h FILE: ../../../third_party/skia/src/core/SkDeferredDisplayListRecorder.cpp FILE: ../../../third_party/skia/src/core/SkDrawShadowInfo.cpp FILE: ../../../third_party/skia/src/core/SkDrawShadowInfo.h @@ -4562,7 +3966,6 @@ FILE: ../../../third_party/skia/src/core/SkVptr.h FILE: ../../../third_party/skia/src/core/SkWritePixelsRec.h FILE: ../../../third_party/skia/src/effects/SkDashImpl.h FILE: ../../../third_party/skia/src/effects/SkHighContrastFilter.cpp -FILE: ../../../third_party/skia/src/effects/SkToSRGBColorFilter.cpp FILE: ../../../third_party/skia/src/gpu/GrAHardwareBufferImageGenerator.cpp FILE: ../../../third_party/skia/src/gpu/GrAHardwareBufferImageGenerator.h FILE: ../../../third_party/skia/src/gpu/GrBackendSurface.cpp @@ -4590,8 +3993,6 @@ FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCClipProcessor.cpp FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCClipProcessor.h FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCCoverageProcessor.cpp FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCCoverageProcessor.h -FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp -FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCCubicShader.cpp FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCCubicShader.h FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCFillGeometry.cpp @@ -4604,19 +4005,21 @@ FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCQuadraticShader.cpp FILE: ../../../third_party/skia/src/gpu/ccpr/GrCCQuadraticShader.h FILE: ../../../third_party/skia/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp FILE: ../../../third_party/skia/src/gpu/ccpr/GrCoverageCountingPathRenderer.h +FILE: ../../../third_party/skia/src/gpu/ccpr/GrGSCoverageProcessor.cpp +FILE: ../../../third_party/skia/src/gpu/ccpr/GrVSCoverageProcessor.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrAtlasedShaderHelpers.h -FILE: ../../../third_party/skia/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrBlurredEdgeFragmentProcessor.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h -FILE: ../../../third_party/skia/src/gpu/effects/GrCircleEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrCircleEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrCircleEffect.h -FILE: ../../../third_party/skia/src/gpu/effects/GrEllipseEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrEllipseEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrEllipseEffect.h -FILE: ../../../third_party/skia/src/gpu/effects/GrSimpleTextureEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrSimpleTextureEffect.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrSimpleTextureEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrCircleEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrCircleEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrEllipseEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrEllipseEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrSimpleTextureEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrSimpleTextureEffect.h FILE: ../../../third_party/skia/src/gpu/gl/GrGLGpuCommandBuffer.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLSemaphore.cpp FILE: ../../../third_party/skia/src/gpu/gl/GrGLSemaphore.h @@ -4793,12 +4196,1115 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/experimental/canvaskit/WasmAliases.h + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/bench/ShaperBench.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/experimental/canvaskit/WasmAliases.h -FILE: ../../../third_party/skia/experimental/canvaskit/skottie_bindings.cpp +FILE: ../../../third_party/skia/bench/ShaperBench.cpp +FILE: ../../../third_party/skia/docs/examples/Alpha_Constants_a.cpp +FILE: ../../../third_party/skia/docs/examples/Alpha_Constants_b.cpp +FILE: ../../../third_party/skia/docs/examples/Alpha_Type_Opaque.cpp +FILE: ../../../third_party/skia/docs/examples/Alpha_Type_Premul.cpp +FILE: ../../../third_party/skia/docs/examples/Alpha_Type_Unpremul.cpp +FILE: ../../../third_party/skia/docs/examples/Anti_Alias.cpp +FILE: ../../../third_party/skia/docs/examples/Arc.cpp +FILE: ../../../third_party/skia/docs/examples/AutoCanvasRestore_SkCanvas_star.cpp +FILE: ../../../third_party/skia/docs/examples/AutoCanvasRestore_restore.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_012.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_ComputeIsOpaque.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_HeapAllocator_allocPixelRef.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_allocN32Pixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_allocPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_allocPixelsFlags.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_allocPixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_allocPixels_3.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_allocPixels_4.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_bounds.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_bytesPerPixel.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_colorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_colorType.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_computeByteSize.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_copy_const_SkBitmap.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_copy_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_dimensions.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_drawsNothing.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_empty.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_erase.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_eraseARGB.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_eraseColor.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_extractAlpha.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_extractAlpha_2.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_extractAlpha_3.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_extractSubset.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getAddr.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getAddr16.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getAddr32.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getAddr8.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getBounds.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getBounds_2.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getColor.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getGenerationID.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_getSubset.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_height.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_info.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_installPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_installPixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_installPixels_3.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_isImmutable.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_isNull.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_isOpaque.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_isVolatile.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_move_SkBitmap.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_move_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_notifyPixelsChanged.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_peekPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_pixelRef.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_pixelRefOrigin.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_pixmap.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_readPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_readPixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_readPixels_3.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_readyToDraw.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_refColorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_reset.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_rowBytes.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_rowBytesAsPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_setAlphaType.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_setImmutable.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_setInfo.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_setIsVolatile.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_setPixelRef.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_setPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_shiftPerPixel.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_swap.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_tryAllocN32Pixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_tryAllocPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_tryAllocPixelsFlags.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_tryAllocPixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_tryAllocPixels_3.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_tryAllocPixels_4.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_width.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_writePixels.cpp +FILE: ../../../third_party/skia/docs/examples/Bitmap_writePixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/BlendMode_Name.cpp +FILE: ../../../third_party/skia/docs/examples/Blend_Mode_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_129.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_MakeRasterDirect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_MakeRasterDirectN32.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_PointMode.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_SaveLayerRec.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_SaveLayerRec_SaveLayerRec.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_SaveLayerRec_const_SkRect_star_const_SkPaint_star.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_SaveLayerRec_const_SkRect_star_const_SkPaint_star_const_SkImageFilter_star.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_SrcRectConstraint.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_accessTopLayerPixels_a.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_accessTopLayerPixels_b.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_accessTopRasterHandle.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clear.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipPath.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipPath_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipPath_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipRRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipRRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipRRect_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipRect_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_clipRegion.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_concat.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_const_SkBitmap_const_SkSurfaceProps.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_copy_const_SkBitmap.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_destructor.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawAnnotation_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawArc_a.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawArc_b.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawAtlas.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawAtlas_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawAtlas_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawAtlas_4.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawBitmap.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawBitmapLattice.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawBitmapNine.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawBitmapRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawBitmapRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawBitmapRect_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawCircle.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawCircle_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawColor.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawDRRect_a.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawDRRect_b.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawDrawable.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawDrawable_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawIRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImage.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImageNine.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImageNine_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImageRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImageRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImageRect_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImageRect_4.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImageRect_5.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImageRect_6.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawImage_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawLine.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawLine_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawOval.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPaint.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPatch.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPatch_2_a.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPatch_2_b.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPath.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPicture_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPicture_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPicture_4.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPoint.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPoint_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPoints.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPosText.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawPosTextH.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawRRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawRegion.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawRoundRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawString.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawString_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawText.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawTextBlob.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawTextBlob_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawTextRSXform.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawVertices.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_drawVertices_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getBaseLayerSize.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getDeviceClipBounds.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getDeviceClipBounds_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getGrContext.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getLocalClipBounds.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getLocalClipBounds_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getProps.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getSaveCount.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_getTotalMatrix.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_imageInfo.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_int_int_const_SkSurfaceProps_star.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_isClipEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_isClipRect.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_kInitWithPrevious_SaveLayerFlag.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_makeSurface.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_peekPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_quickReject.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_quickReject_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_readPixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_readPixels_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_readPixels_a.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_readPixels_b.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_resetMatrix.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_restore.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_restoreToCount.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_rotate.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_rotate_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_save.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_saveLayer.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_saveLayerAlpha.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_saveLayerPreserveLCDTextRequests.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_saveLayer_2.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_saveLayer_3.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_scale.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_setMatrix.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_skew.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_translate.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_writePixels.cpp +FILE: ../../../third_party/skia/docs/examples/Canvas_writePixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Clear.cpp +FILE: ../../../third_party/skia/docs/examples/Clip.cpp +FILE: ../../../third_party/skia/docs/examples/Color.cpp +FILE: ../../../third_party/skia/docs/examples/ColorGetA.cpp +FILE: ../../../third_party/skia/docs/examples/ColorGetB.cpp +FILE: ../../../third_party/skia/docs/examples/ColorGetG.cpp +FILE: ../../../third_party/skia/docs/examples/ColorGetR.cpp +FILE: ../../../third_party/skia/docs/examples/ColorSetA.cpp +FILE: ../../../third_party/skia/docs/examples/ColorSetARGB.cpp +FILE: ../../../third_party/skia/docs/examples/ColorSetRGB.cpp +FILE: ../../../third_party/skia/docs/examples/ColorToHSV.cpp +FILE: ../../../third_party/skia/docs/examples/ColorTypeBytesPerPixel.cpp +FILE: ../../../third_party/skia/docs/examples/ColorTypeIsAlwaysOpaque.cpp +FILE: ../../../third_party/skia/docs/examples/ColorTypeValidateAlphaType.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Burn.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Constants_a.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Constants_b.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Constants_c.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Constants_d.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Dodge.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Filter_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_ARGB_4444.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_Alpha_8.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_BGRA_8888.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_Gray_8.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_RGBA_1010102.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_RGBA_8888.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_RGBA_F16.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_RGB_101010.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_RGB_565.cpp +FILE: ../../../third_party/skia/docs/examples/Color_Type_RGB_888.cpp +FILE: ../../../third_party/skia/docs/examples/Colors.cpp +FILE: ../../../third_party/skia/docs/examples/Conic_Weight_a.cpp +FILE: ../../../third_party/skia/docs/examples/Conic_Weight_b.cpp +FILE: ../../../third_party/skia/docs/examples/Conic_Weight_c.cpp +FILE: ../../../third_party/skia/docs/examples/Cubic.cpp +FILE: ../../../third_party/skia/docs/examples/Darken.cpp +FILE: ../../../third_party/skia/docs/examples/Device_Text.cpp +FILE: ../../../third_party/skia/docs/examples/Difference.cpp +FILE: ../../../third_party/skia/docs/examples/Dither_a.cpp +FILE: ../../../third_party/skia/docs/examples/Dither_b.cpp +FILE: ../../../third_party/skia/docs/examples/Draw_Looper_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Dst.cpp +FILE: ../../../third_party/skia/docs/examples/Dst_Atop.cpp +FILE: ../../../third_party/skia/docs/examples/Dst_In.cpp +FILE: ../../../third_party/skia/docs/examples/Dst_Out.cpp +FILE: ../../../third_party/skia/docs/examples/Dst_Over.cpp +FILE: ../../../third_party/skia/docs/examples/Exclusion.cpp +FILE: ../../../third_party/skia/docs/examples/Fake_Bold.cpp +FILE: ../../../third_party/skia/docs/examples/Filter_Quality_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Font_breakText.cpp +FILE: ../../../third_party/skia/docs/examples/HSVToColor.cpp +FILE: ../../../third_party/skia/docs/examples/HSVToColor_2.cpp +FILE: ../../../third_party/skia/docs/examples/Hard_Light.cpp +FILE: ../../../third_party/skia/docs/examples/Hue.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_Make.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_add_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_addto_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_equal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_equals.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_isZero.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_minus_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_notequal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_set.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_subtract_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_subtractfrom_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_x.cpp +FILE: ../../../third_party/skia/docs/examples/IPoint_y.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_EmptyIRect.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_Intersects.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_IntersectsNoEmptyCheck.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_MakeEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_MakeLTRB.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_MakeSize.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_MakeWH.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_MakeXYWH.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_adjust.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_bottom.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_contains.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_containsNoEmptyCheck.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_containsNoEmptyCheck_2.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_contains_2.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_contains_3.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_contains_4.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_equal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_height.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_height64.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_inset.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_intersect.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_intersectNoEmptyCheck.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_intersect_2.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_intersect_3.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_isEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_isEmpty64.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_join.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_join_2.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_left.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_makeInset.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_makeOffset.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_makeOutset.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_makeSorted.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_notequal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_offset.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_offsetTo.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_offset_2.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_outset.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_right.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_set.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_setEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_setLTRB.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_setXYWH.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_size.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_sort.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_top.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_width.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_width64.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_x.cpp +FILE: ../../../third_party/skia/docs/examples/IRect_y.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_ByteSizeOverflowed.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_Make.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_MakeA8.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_MakeN32.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_MakeN32Premul.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_MakeN32Premul_2.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_MakeS32.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_MakeUnknown.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_MakeUnknown_2.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_alphaType.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_bounds.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_bytesPerPixel.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_colorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_colorType.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_computeByteSize.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_computeMinByteSize.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_computeOffset.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_dimensions.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_equal1_operator.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_gammaCloseToSRGB.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_height.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_isEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_isOpaque.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_makeAlphaType.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_makeColorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_makeColorType.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_makeWH.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_minRowBytes.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_minRowBytes64.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_notequal1_operator.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_refColorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_reset.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_shiftPerPixel.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_validRowBytes.cpp +FILE: ../../../third_party/skia/docs/examples/ImageInfo_width.cpp +FILE: ../../../third_party/skia/docs/examples/Image_Filter_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeBackendTextureFromSkImage.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeCrossContextFromEncoded.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeCrossContextFromPixmap.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeFromAdoptedTexture.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeFromBitmap.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeFromEncoded.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeFromGenerator.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeFromPicture.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeFromRaster.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeFromTexture.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeFromTexture_2.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeRasterCopy.cpp +FILE: ../../../third_party/skia/docs/examples/Image_MakeRasterData.cpp +FILE: ../../../third_party/skia/docs/examples/Image_alphaType.cpp +FILE: ../../../third_party/skia/docs/examples/Image_bounds.cpp +FILE: ../../../third_party/skia/docs/examples/Image_colorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/Image_colorType.cpp +FILE: ../../../third_party/skia/docs/examples/Image_dimensions.cpp +FILE: ../../../third_party/skia/docs/examples/Image_encodeToData.cpp +FILE: ../../../third_party/skia/docs/examples/Image_encodeToData_2.cpp +FILE: ../../../third_party/skia/docs/examples/Image_getBackendTexture.cpp +FILE: ../../../third_party/skia/docs/examples/Image_height.cpp +FILE: ../../../third_party/skia/docs/examples/Image_isAlphaOnly.cpp +FILE: ../../../third_party/skia/docs/examples/Image_isLazyGenerated_a.cpp +FILE: ../../../third_party/skia/docs/examples/Image_isLazyGenerated_b.cpp +FILE: ../../../third_party/skia/docs/examples/Image_isOpaque.cpp +FILE: ../../../third_party/skia/docs/examples/Image_isTextureBacked.cpp +FILE: ../../../third_party/skia/docs/examples/Image_isValid.cpp +FILE: ../../../third_party/skia/docs/examples/Image_makeColorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/Image_makeNonTextureImage.cpp +FILE: ../../../third_party/skia/docs/examples/Image_makeRasterImage.cpp +FILE: ../../../third_party/skia/docs/examples/Image_makeShader.cpp +FILE: ../../../third_party/skia/docs/examples/Image_makeShader_2.cpp +FILE: ../../../third_party/skia/docs/examples/Image_makeSubset.cpp +FILE: ../../../third_party/skia/docs/examples/Image_makeTextureImage.cpp +FILE: ../../../third_party/skia/docs/examples/Image_makeWithFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Image_peekPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Image_readPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Image_readPixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Image_refColorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/Image_refEncodedData.cpp +FILE: ../../../third_party/skia/docs/examples/Image_scalePixels.cpp +FILE: ../../../third_party/skia/docs/examples/Image_uniqueID.cpp +FILE: ../../../third_party/skia/docs/examples/Image_width.cpp +FILE: ../../../third_party/skia/docs/examples/Lighten.cpp +FILE: ../../../third_party/skia/docs/examples/Luminosity.cpp +FILE: ../../../third_party/skia/docs/examples/Mask_Filter_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_063.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_Concat.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_I.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_InvalidMatrix.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_MakeAll.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_MakeRectToRect.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_MakeScale.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_MakeScale_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_MakeTrans.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_ScaleToFit.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_SetAffineIdentity.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_TypeMask.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_array_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_asAffine.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_cheapEqualTo.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_decomposeScale.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_dirtyMatrixTypeCache.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_dump.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_equal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_fixedStepInX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_get.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_get9.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getMaxScale.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getMinMaxScales.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getMinScale.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getPerspX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getPerspY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getScaleX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getScaleY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getSkewX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getSkewY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getTranslateX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getTranslateY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_getType.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_hasPerspective.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_invert.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_isFinite.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_isFixedStepInX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_isIdentity.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_isScaleTranslate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_isSimilarity.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_isTranslate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapHomogeneousPoints.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapPoints.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapPoints_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapRadius.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapRect.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapRectScaleTranslate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapRectToQuad.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapRect_3.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapVector.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapVector_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapVectors.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapVectors_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapXY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_mapXY_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_notequal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_postConcat.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_postRotate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_postRotate_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_postScale.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_postScale_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_postSkew.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_postSkew_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_postTranslate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preConcat.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preRotate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preRotate_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preScale.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preScale_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preSkew.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preSkew_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preTranslate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preservesAxisAlignment.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_preservesRightAngles.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_rectStaysRect.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_reset.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_set.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_set9.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setAffine.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setAll.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setConcat.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setIdentity.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setPerspX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setPerspY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setPolyToPoly.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setRSXform.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setRectToRect.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setRotate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setRotate_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setScale.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setScaleTranslate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setScaleX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setScaleY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setScale_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setSinCos.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setSinCos_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setSkew.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setSkewX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setSkewY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setSkew_2.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setTranslate.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setTranslateX.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setTranslateY.cpp +FILE: ../../../third_party/skia/docs/examples/Matrix_setTranslate_2.cpp +FILE: ../../../third_party/skia/docs/examples/MemberIndex.cpp +FILE: ../../../third_party/skia/docs/examples/Miter_Limit.cpp +FILE: ../../../third_party/skia/docs/examples/Modulate.cpp +FILE: ../../../third_party/skia/docs/examples/Multiply.cpp +FILE: ../../../third_party/skia/docs/examples/Overlay.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_053.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_057.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_containsText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_copy_const_SkPaint.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_copy_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_countText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_equal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getAlpha.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getBlendMode.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getColor.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getColor4f.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getColorFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getDrawLooper.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getFillPath.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getFillPath_2.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getFilterQuality.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getFlags.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getFontMetrics.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getFontSpacing.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getHash.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getHinting.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getImageFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getMaskFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getPathEffect.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getPosTextPath.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getShader.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getStrokeCap.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getStrokeJoin.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getStrokeMiter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getStrokeWidth.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getStyle.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getTextEncoding.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getTextPath.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getTextScaleX.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getTextSize.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getTextSkewX.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getTextWidths.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_getTypeface.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_isAntiAlias.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_isAutohinted.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_isDither.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_isEmbeddedBitmapText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_isFakeBoldText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_isLCDRenderText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_isLinearText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_isSubpixelText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_measureText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_measureText_2.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_move_SkPaint.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_move_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_notequal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_nothingToDraw.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_refColorFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_refDrawLooper.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_refImageFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_refMaskFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_refPathEffect.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_refShader.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_refTypeface.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_reset.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setARGB.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setAlpha.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setAntiAlias.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setAutohinted.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setBlendMode.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setColor.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setColor4f.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setColorFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setDither.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setDrawLooper.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setEmbeddedBitmapText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setFakeBoldText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setFilterQuality.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setFlags.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setHinting.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setImageFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setLCDRenderText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setLinearText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setMaskFilter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setPathEffect.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setShader.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setStrokeCap_a.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setStrokeCap_b.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setStrokeJoin.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setStrokeMiter.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setStrokeWidth.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setStyle.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setSubpixelText.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setTextEncoding.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setTextScaleX.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setTextSize.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setTextSkewX.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_setTypeface.cpp +FILE: ../../../third_party/skia/docs/examples/Paint_textToGlyphs.cpp +FILE: ../../../third_party/skia/docs/examples/Path_AddPathMode.cpp +FILE: ../../../third_party/skia/docs/examples/Path_ArcSize.cpp +FILE: ../../../third_party/skia/docs/examples/Path_ConvertConicToQuads.cpp +FILE: ../../../third_party/skia/docs/examples/Path_ConvertToNonInverseFillType.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Convexity.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Direction.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Effect_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Path_FillType_a.cpp +FILE: ../../../third_party/skia/docs/examples/Path_FillType_b.cpp +FILE: ../../../third_party/skia/docs/examples/Path_IsCubicDegenerate.cpp +FILE: ../../../third_party/skia/docs/examples/Path_IsInverseFillType.cpp +FILE: ../../../third_party/skia/docs/examples/Path_IsLineDegenerate.cpp +FILE: ../../../third_party/skia/docs/examples/Path_IsQuadDegenerate.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Iter.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Iter_Iter.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Iter_conicWeight.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Iter_const_SkPath.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Iter_isCloseLine.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Iter_isClosedContour.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Iter_next.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Iter_setPath.cpp +FILE: ../../../third_party/skia/docs/examples/Path_RawIter_conicWeight.cpp +FILE: ../../../third_party/skia/docs/examples/Path_RawIter_next.cpp +FILE: ../../../third_party/skia/docs/examples/Path_RawIter_peek.cpp +FILE: ../../../third_party/skia/docs/examples/Path_SegmentMask.cpp +FILE: ../../../third_party/skia/docs/examples/Path_Verb.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addArc.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addCircle.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addOval.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addOval_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addPath.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addPath_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addPath_3.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addPoly.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addPoly_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addRRect.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addRRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addRect.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addRect_3.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addRoundRect.cpp +FILE: ../../../third_party/skia/docs/examples/Path_addRoundRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_arcTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_arcTo_2_a.cpp +FILE: ../../../third_party/skia/docs/examples/Path_arcTo_2_b.cpp +FILE: ../../../third_party/skia/docs/examples/Path_arcTo_2_c.cpp +FILE: ../../../third_party/skia/docs/examples/Path_arcTo_3.cpp +FILE: ../../../third_party/skia/docs/examples/Path_arcTo_4.cpp +FILE: ../../../third_party/skia/docs/examples/Path_close.cpp +FILE: ../../../third_party/skia/docs/examples/Path_computeTightBounds.cpp +FILE: ../../../third_party/skia/docs/examples/Path_conicTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_conicTo_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_conservativelyContainsRect.cpp +FILE: ../../../third_party/skia/docs/examples/Path_contains.cpp +FILE: ../../../third_party/skia/docs/examples/Path_copy_const_SkPath.cpp +FILE: ../../../third_party/skia/docs/examples/Path_copy_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Path_countPoints.cpp +FILE: ../../../third_party/skia/docs/examples/Path_countVerbs.cpp +FILE: ../../../third_party/skia/docs/examples/Path_cubicTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_cubicTo_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_destructor.cpp +FILE: ../../../third_party/skia/docs/examples/Path_dump.cpp +FILE: ../../../third_party/skia/docs/examples/Path_dumpHex.cpp +FILE: ../../../third_party/skia/docs/examples/Path_dump_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/Path_equal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getBounds.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getConvexity.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getConvexityOrUnknown.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getFillType.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getGenerationID.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getLastPt.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getPoint.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getPoints.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getSegmentMasks.cpp +FILE: ../../../third_party/skia/docs/examples/Path_getVerbs.cpp +FILE: ../../../third_party/skia/docs/examples/Path_incReserve.cpp +FILE: ../../../third_party/skia/docs/examples/Path_interpolate.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isConvex.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isFinite.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isInterpolatable.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isInverseFillType_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isLastContourClosed.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isLine.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isNestedFillRects.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isOval.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isRRect.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isRect.cpp +FILE: ../../../third_party/skia/docs/examples/Path_isVolatile.cpp +FILE: ../../../third_party/skia/docs/examples/Path_lineTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_lineTo_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_moveTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_moveTo_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_notequal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Path_offset.cpp +FILE: ../../../third_party/skia/docs/examples/Path_offset_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_quadTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_quadTo_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_rArcTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_rConicTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_rCubicTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_rLineTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_rMoveTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_rQuadTo.cpp +FILE: ../../../third_party/skia/docs/examples/Path_readFromMemory.cpp +FILE: ../../../third_party/skia/docs/examples/Path_reset.cpp +FILE: ../../../third_party/skia/docs/examples/Path_reverseAddPath.cpp +FILE: ../../../third_party/skia/docs/examples/Path_rewind.cpp +FILE: ../../../third_party/skia/docs/examples/Path_serialize.cpp +FILE: ../../../third_party/skia/docs/examples/Path_setConvexity.cpp +FILE: ../../../third_party/skia/docs/examples/Path_setFillType.cpp +FILE: ../../../third_party/skia/docs/examples/Path_setIsVolatile.cpp +FILE: ../../../third_party/skia/docs/examples/Path_setLastPt.cpp +FILE: ../../../third_party/skia/docs/examples/Path_setLastPt_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_swap.cpp +FILE: ../../../third_party/skia/docs/examples/Path_toggleInverseFillType.cpp +FILE: ../../../third_party/skia/docs/examples/Path_transform.cpp +FILE: ../../../third_party/skia/docs/examples/Path_transform_2.cpp +FILE: ../../../third_party/skia/docs/examples/Path_updateBoundsCache.cpp +FILE: ../../../third_party/skia/docs/examples/Path_writeToMemory.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_008.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_AbortCallback_abort.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_MakeFromData.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_MakeFromStream.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_MakePlaceholder.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_approximateBytesUsed.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_approximateOpCount.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_cullRect.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_playback.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_serialize.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_serialize_2.cpp +FILE: ../../../third_party/skia/docs/examples/Picture_uniqueID.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr16.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr16_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr32.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr32_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr64.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr64_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr8.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr8_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addrF16.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addrF16_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_addr_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_alphaType.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_bounds.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_colorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_colorType.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_computeByteSize.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_computeIsOpaque.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_const_SkImageInfo_const_star.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_erase.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_erase_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_erase_3.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_extractSubset.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_getColor.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_height.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_info.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_isOpaque.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_readPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_readPixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_readPixels_3.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_readPixels_4.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_reset.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_reset_2.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_rowBytes.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_rowBytesAsPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_scalePixels.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_setColorSpace.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_shiftPerPixel.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_width.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_writable_addr.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_writable_addr16.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_writable_addr32.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_writable_addr64.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_writable_addr8.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_writable_addrF16.cpp +FILE: ../../../third_party/skia/docs/examples/Pixmap_writable_addr_2.cpp +FILE: ../../../third_party/skia/docs/examples/Plus.cpp +FILE: ../../../third_party/skia/docs/examples/Point_CrossProduct.cpp +FILE: ../../../third_party/skia/docs/examples/Point_Distance.cpp +FILE: ../../../third_party/skia/docs/examples/Point_DotProduct.cpp +FILE: ../../../third_party/skia/docs/examples/Point_Length.cpp +FILE: ../../../third_party/skia/docs/examples/Point_Make.cpp +FILE: ../../../third_party/skia/docs/examples/Point_Normalize.cpp +FILE: ../../../third_party/skia/docs/examples/Point_Offset.cpp +FILE: ../../../third_party/skia/docs/examples/Point_Offset_2.cpp +FILE: ../../../third_party/skia/docs/examples/Point_add_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_addto_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_cross.cpp +FILE: ../../../third_party/skia/docs/examples/Point_distanceToOrigin.cpp +FILE: ../../../third_party/skia/docs/examples/Point_dot.cpp +FILE: ../../../third_party/skia/docs/examples/Point_equal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_equals.cpp +FILE: ../../../third_party/skia/docs/examples/Point_isFinite.cpp +FILE: ../../../third_party/skia/docs/examples/Point_isZero.cpp +FILE: ../../../third_party/skia/docs/examples/Point_iset.cpp +FILE: ../../../third_party/skia/docs/examples/Point_iset_2.cpp +FILE: ../../../third_party/skia/docs/examples/Point_length_2.cpp +FILE: ../../../third_party/skia/docs/examples/Point_minus_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_multiply_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_multiplyby_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_negate.cpp +FILE: ../../../third_party/skia/docs/examples/Point_normalize_2.cpp +FILE: ../../../third_party/skia/docs/examples/Point_notequal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_offset_3.cpp +FILE: ../../../third_party/skia/docs/examples/Point_scale.cpp +FILE: ../../../third_party/skia/docs/examples/Point_scale_2.cpp +FILE: ../../../third_party/skia/docs/examples/Point_set.cpp +FILE: ../../../third_party/skia/docs/examples/Point_setAbs.cpp +FILE: ../../../third_party/skia/docs/examples/Point_setLength.cpp +FILE: ../../../third_party/skia/docs/examples/Point_setLength_2.cpp +FILE: ../../../third_party/skia/docs/examples/Point_setNormalize.cpp +FILE: ../../../third_party/skia/docs/examples/Point_subtract_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_subtractfrom_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Point_x.cpp +FILE: ../../../third_party/skia/docs/examples/Point_y.cpp +FILE: ../../../third_party/skia/docs/examples/PreMultiplyARGB.cpp +FILE: ../../../third_party/skia/docs/examples/PreMultiplyColor.cpp +FILE: ../../../third_party/skia/docs/examples/Quad_a.cpp +FILE: ../../../third_party/skia/docs/examples/Quad_b.cpp +FILE: ../../../third_party/skia/docs/examples/RGBA4f_FromColor.cpp +FILE: ../../../third_party/skia/docs/examples/RGBA4f_equal1_operator.cpp +FILE: ../../../third_party/skia/docs/examples/RGBA4f_notequal1_operator.cpp +FILE: ../../../third_party/skia/docs/examples/RGBA4f_toSkColor.cpp +FILE: ../../../third_party/skia/docs/examples/RGBA4f_vec.cpp +FILE: ../../../third_party/skia/docs/examples/RGBA4f_vec_2.cpp +FILE: ../../../third_party/skia/docs/examples/RGBToHSV.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_Corner.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_MakeEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_MakeOval.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_MakeRect.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_MakeRectXY.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_Type.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_contains.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_copy_const_SkRRect.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_copy_operator.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_dump.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_dumpHex.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_dump_2.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_equal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_getBounds.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_getSimpleRadii.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_getType.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_height.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_inset.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_inset_2.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_isComplex.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_isEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_isNinePatch.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_isOval.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_isRect.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_isSimple.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_isValid.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_makeOffset.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_notequal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_offset.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_outset.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_outset_2.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_radii.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_readFromMemory.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_rect.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_setEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_setNinePatch.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_setOval.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_setRect.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_setRectRadii.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_setRectXY.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_transform.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_type_2.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_width.cpp +FILE: ../../../third_party/skia/docs/examples/RRect_writeToMemory.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_Intersects.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_Make.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_MakeEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_MakeIWH.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_MakeLTRB.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_MakeSize.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_MakeWH.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_MakeXYWH.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_Make_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_asScalars.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_bottom.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_centerX.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_centerY.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_contains.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_contains_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_contains_3.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_dump.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_dumpHex.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_dump_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_equal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_height.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_inset.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_intersect.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_intersect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_intersect_3.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_intersects_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_intersects_3.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_isEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_isFinite.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_isSorted.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_iset.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_isetWH.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_join.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_joinNonEmptyArg.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_joinPossiblyEmptyRect.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_join_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_left.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_makeInset.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_makeOffset.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_makeOutset.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_makeSorted.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_notequal_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_offset.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_offsetTo.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_offset_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_outset.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_right.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_round.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_roundIn.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_roundOut.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_roundOut_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_roundOut_3.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_round_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_set.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_setBounds.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_setBoundsCheck.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_setBoundsNoCheck.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_setEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_setLTRB.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_setWH.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_setXYWH.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_set_2.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_set_3.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_set_4.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_sort.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_toQuad.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_top.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_width.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_x.cpp +FILE: ../../../third_party/skia/docs/examples/Rect_y.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Cliperator_const_SkRegion_const_SkIRect.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Cliperator_done.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Cliperator_next.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Cliperator_rect.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Iterator_Iterator.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Iterator_copy_const_SkRegion.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Iterator_done.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Iterator_next.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Iterator_rect.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Iterator_reset.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Iterator_rewind.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Iterator_rgn.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Op.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Spanerator_const_SkRegion_int_int_int.cpp +FILE: ../../../third_party/skia/docs/examples/Region_Spanerator_next.cpp +FILE: ../../../third_party/skia/docs/examples/Region_computeRegionComplexity.cpp +FILE: ../../../third_party/skia/docs/examples/Region_contains.cpp +FILE: ../../../third_party/skia/docs/examples/Region_contains_2.cpp +FILE: ../../../third_party/skia/docs/examples/Region_contains_3.cpp +FILE: ../../../third_party/skia/docs/examples/Region_copy_const_SkIRect.cpp +FILE: ../../../third_party/skia/docs/examples/Region_copy_const_SkRegion.cpp +FILE: ../../../third_party/skia/docs/examples/Region_copy_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Region_destructor.cpp +FILE: ../../../third_party/skia/docs/examples/Region_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/Region_equal1_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Region_getBoundaryPath.cpp +FILE: ../../../third_party/skia/docs/examples/Region_getBounds.cpp +FILE: ../../../third_party/skia/docs/examples/Region_intersects.cpp +FILE: ../../../third_party/skia/docs/examples/Region_intersects_2.cpp +FILE: ../../../third_party/skia/docs/examples/Region_isComplex.cpp +FILE: ../../../third_party/skia/docs/examples/Region_isEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/Region_isRect.cpp +FILE: ../../../third_party/skia/docs/examples/Region_notequal1_operator.cpp +FILE: ../../../third_party/skia/docs/examples/Region_op_1.cpp +FILE: ../../../third_party/skia/docs/examples/Region_op_2.cpp +FILE: ../../../third_party/skia/docs/examples/Region_op_3.cpp +FILE: ../../../third_party/skia/docs/examples/Region_op_4.cpp +FILE: ../../../third_party/skia/docs/examples/Region_op_5.cpp +FILE: ../../../third_party/skia/docs/examples/Region_op_6.cpp +FILE: ../../../third_party/skia/docs/examples/Region_quickContains.cpp +FILE: ../../../third_party/skia/docs/examples/Region_quickContains_2.cpp +FILE: ../../../third_party/skia/docs/examples/Region_quickReject.cpp +FILE: ../../../third_party/skia/docs/examples/Region_quickReject_2.cpp +FILE: ../../../third_party/skia/docs/examples/Region_readFromMemory.cpp +FILE: ../../../third_party/skia/docs/examples/Region_set.cpp +FILE: ../../../third_party/skia/docs/examples/Region_setEmpty.cpp +FILE: ../../../third_party/skia/docs/examples/Region_setPath.cpp +FILE: ../../../third_party/skia/docs/examples/Region_setRect.cpp +FILE: ../../../third_party/skia/docs/examples/Region_setRect_2.cpp +FILE: ../../../third_party/skia/docs/examples/Region_setRects.cpp +FILE: ../../../third_party/skia/docs/examples/Region_setRegion.cpp +FILE: ../../../third_party/skia/docs/examples/Region_swap.cpp +FILE: ../../../third_party/skia/docs/examples/Region_translate.cpp +FILE: ../../../third_party/skia/docs/examples/Region_translate_2.cpp +FILE: ../../../third_party/skia/docs/examples/Region_writeToMemory.cpp +FILE: ../../../third_party/skia/docs/examples/Saturation.cpp +FILE: ../../../third_party/skia/docs/examples/Screen.cpp +FILE: ../../../third_party/skia/docs/examples/Shader_Methods_a.cpp +FILE: ../../../third_party/skia/docs/examples/Shader_Methods_b.cpp +FILE: ../../../third_party/skia/docs/examples/Soft_Light.cpp +FILE: ../../../third_party/skia/docs/examples/Src.cpp +FILE: ../../../third_party/skia/docs/examples/Src_Atop.cpp +FILE: ../../../third_party/skia/docs/examples/Src_In.cpp +FILE: ../../../third_party/skia/docs/examples/Src_Out.cpp +FILE: ../../../third_party/skia/docs/examples/Src_Over.cpp +FILE: ../../../third_party/skia/docs/examples/State_Stack_a.cpp +FILE: ../../../third_party/skia/docs/examples/State_Stack_b.cpp +FILE: ../../../third_party/skia/docs/examples/Stroke_Width.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeFromBackendTexture.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeFromBackendTextureAsRenderTarget.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeNull.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeRaster.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeRasterDirect.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeRasterDirectReleaseProc.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeRasterN32Premul.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeRaster_2.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeRenderTarget.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeRenderTarget_2.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_MakeRenderTarget_3.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_characterize.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_draw.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_draw_2.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_getCanvas.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_height.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_makeImageSnapshot.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_makeImageSnapshot_2.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_makeSurface.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_notifyContentWillChange.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_peekPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_props.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_readPixels.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_readPixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_readPixels_3.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_width.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_writePixels.cpp +FILE: ../../../third_party/skia/docs/examples/Surface_writePixels_2.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlobBuilder_allocRun.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlobBuilder_allocRunPos.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlobBuilder_allocRunPosH.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlobBuilder_empty_constructor.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlobBuilder_make.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlob_Deserialize.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlob_MakeFromString.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlob_MakeFromText.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlob_bounds.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlob_getIntercepts.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlob_serialize.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlob_serialize_2.cpp +FILE: ../../../third_party/skia/docs/examples/TextBlob_uniqueID.cpp +FILE: ../../../third_party/skia/docs/examples/Text_Encoding.cpp +FILE: ../../../third_party/skia/docs/examples/Text_Scale_X.cpp +FILE: ../../../third_party/skia/docs/examples/Text_Size.cpp +FILE: ../../../third_party/skia/docs/examples/Text_Skew_X.cpp +FILE: ../../../third_party/skia/docs/examples/Typeface_Methods.cpp +FILE: ../../../third_party/skia/docs/examples/Xor.cpp +FILE: ../../../third_party/skia/experimental/editor/editor.cpp +FILE: ../../../third_party/skia/experimental/editor/editor.h +FILE: ../../../third_party/skia/experimental/editor/editor_application.cpp +FILE: ../../../third_party/skia/experimental/editor/run_handler.cpp +FILE: ../../../third_party/skia/experimental/editor/run_handler.h +FILE: ../../../third_party/skia/experimental/editor/stringslice.cpp +FILE: ../../../third_party/skia/experimental/editor/stringslice.h +FILE: ../../../third_party/skia/gm/crbug_918512.cpp +FILE: ../../../third_party/skia/gm/tilemodes_alpha.cpp +FILE: ../../../third_party/skia/src/gpu/GrPersistentCacheUtils.h +FILE: ../../../third_party/skia/src/gpu/effects/GrComposeLerpEffect.fp +FILE: ../../../third_party/skia/src/gpu/effects/GrComposeLerpRedEffect.fp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrComposeLerpEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrComposeLerpEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrComposeLerpRedEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrComposeLerpRedEffect.h +FILE: ../../../third_party/skia/src/pdf/SkPDFGraphicStackState.cpp +FILE: ../../../third_party/skia/src/pdf/SkPDFGraphicStackState.h +FILE: ../../../third_party/skia/src/pdf/SkPDFType1Font.cpp +FILE: ../../../third_party/skia/src/pdf/SkPDFType1Font.h ---------------------------------------------------------------------------------------------------- -Copyright 2019 Google LLC +Copyright 2019 Google LLC. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -4829,17 +5335,44 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/experimental/canvaskit/canvaskit_bindings.cpp + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/experimental/wasm-skp-debugger/debugger_bindings.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/experimental/canvaskit/canvaskit_bindings.cpp -FILE: ../../../third_party/skia/fuzz/FuzzEncoders.cpp -FILE: ../../../third_party/skia/fuzz/FuzzPolyUtils.cpp -FILE: ../../../third_party/skia/include/private/GrSkSLFPFactoryCache.h -FILE: ../../../third_party/skia/modules/pathkit/pathkit_wasm_bindings.cpp -FILE: ../../../third_party/skia/src/core/SkPicture_none.cpp -FILE: ../../../third_party/skia/src/gpu/ccpr/GrCoverageCountingPathRenderer_none.cpp +FILE: ../../../third_party/skia/experimental/wasm-skp-debugger/debugger_bindings.cpp +FILE: ../../../third_party/skia/gm/crbug_946965.cpp +FILE: ../../../third_party/skia/gm/runtimecolorfilter.cpp +FILE: ../../../third_party/skia/include/gpu/gl/GrGLAssembleHelpers.h +FILE: ../../../third_party/skia/include/private/SkThreadAnnotations.h +FILE: ../../../third_party/skia/modules/canvaskit/WasmAliases.h +FILE: ../../../third_party/skia/modules/canvaskit/particles_bindings.cpp +FILE: ../../../third_party/skia/modules/canvaskit/skottie_bindings.cpp +FILE: ../../../third_party/skia/modules/particles/include/SkCurve.h +FILE: ../../../third_party/skia/modules/particles/include/SkParticleAffector.h +FILE: ../../../third_party/skia/modules/particles/include/SkParticleData.h +FILE: ../../../third_party/skia/modules/particles/include/SkParticleDrawable.h +FILE: ../../../third_party/skia/modules/particles/include/SkParticleEffect.h +FILE: ../../../third_party/skia/modules/particles/include/SkParticleSerialization.h +FILE: ../../../third_party/skia/modules/particles/include/SkReflected.h +FILE: ../../../third_party/skia/modules/particles/src/SkCurve.cpp +FILE: ../../../third_party/skia/modules/particles/src/SkParticleAffector.cpp +FILE: ../../../third_party/skia/modules/particles/src/SkParticleDrawable.cpp +FILE: ../../../third_party/skia/modules/particles/src/SkParticleEffect.cpp +FILE: ../../../third_party/skia/modules/particles/src/SkReflected.cpp +FILE: ../../../third_party/skia/src/core/SkColorFilterPriv.h +FILE: ../../../third_party/skia/src/gpu/GrShaderUtils.cpp +FILE: ../../../third_party/skia/src/gpu/GrShaderUtils.h +FILE: ../../../third_party/skia/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp +FILE: ../../../third_party/skia/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp +FILE: ../../../third_party/skia/src/gpu/gl/GrGLAssembleHelpers.cpp +FILE: ../../../third_party/skia/src/gpu/gl/GrGLAssembleWebGLInterfaceAutogen.cpp +FILE: ../../../third_party/skia/src/gpu/ops/GrTransferFromOp.cpp +FILE: ../../../third_party/skia/src/gpu/ops/GrTransferFromOp.h +FILE: ../../../third_party/skia/src/sksl/SkSLByteCode.h +FILE: ../../../third_party/skia/src/sksl/SkSLByteCodeGenerator.cpp +FILE: ../../../third_party/skia/src/sksl/SkSLByteCodeGenerator.h +FILE: ../../../third_party/skia/src/sksl/SkSLExternalValue.h +FILE: ../../../third_party/skia/src/sksl/ir/SkSLExternalValueReference.h ---------------------------------------------------------------------------------------------------- -Copyright 2018 Google LLC +Copyright 2019 Google LLC Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -4903,6 +5436,47 @@ 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: ../../../third_party/skia/fuzz/FuzzEncoders.cpp + ../../../third_party/skia/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../third_party/skia/fuzz/FuzzEncoders.cpp +FILE: ../../../third_party/skia/fuzz/FuzzPolyUtils.cpp +FILE: ../../../third_party/skia/include/private/GrSkSLFPFactoryCache.h +FILE: ../../../third_party/skia/modules/canvaskit/canvaskit_bindings.cpp +FILE: ../../../third_party/skia/modules/pathkit/pathkit_wasm_bindings.cpp +FILE: ../../../third_party/skia/src/core/SkPicture_none.cpp +FILE: ../../../third_party/skia/src/gpu/ccpr/GrCoverageCountingPathRenderer_none.cpp +---------------------------------------------------------------------------------------------------- +Copyright 2018 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 Google Inc. 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: ../../../third_party/skia/fuzz/oss_fuzz/FuzzAPIImageFilter.cpp + ../../../third_party/skia/LICENSE @@ -4959,11 +5533,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/gm/circles.cpp + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/fuzz/oss_fuzz/FuzzSKSL2GLSL.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/gm/circles.cpp +FILE: ../../../third_party/skia/fuzz/oss_fuzz/FuzzSKSL2GLSL.cpp +FILE: ../../../third_party/skia/fuzz/oss_fuzz/FuzzSKSL2Metal.cpp +FILE: ../../../third_party/skia/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp +FILE: ../../../third_party/skia/fuzz/oss_fuzz/FuzzSKSL2SPIRV.cpp ---------------------------------------------------------------------------------------------------- -Copyright 2012 Intel Inc. +Copyright 2019 Google, LLC Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -4994,11 +5571,82 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/gm/crbug_918512.cpp + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/gm/backdrop.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/gm/crbug_918512.cpp +FILE: ../../../third_party/skia/gm/backdrop.cpp +FILE: ../../../third_party/skia/gm/backdrop_imagefilter_croprect.cpp +FILE: ../../../third_party/skia/gm/compositor_quads.cpp +FILE: ../../../third_party/skia/gm/crbug_938592.cpp +FILE: ../../../third_party/skia/gm/crbug_947055.cpp +FILE: ../../../third_party/skia/gm/mac_aa_explorer.cpp +FILE: ../../../third_party/skia/gm/mixercolorfilter.cpp +FILE: ../../../third_party/skia/gm/overdrawcanvas.cpp +FILE: ../../../third_party/skia/gm/postercircle.cpp +FILE: ../../../third_party/skia/gm/samplelocations.cpp +FILE: ../../../third_party/skia/gm/skbug_8664.cpp +FILE: ../../../third_party/skia/gm/skbug_8955.cpp +FILE: ../../../third_party/skia/include/core/SkTileMode.h +FILE: ../../../third_party/skia/include/gpu/GrContextThreadSafeProxy.h +FILE: ../../../third_party/skia/include/private/GrContext_Base.h +FILE: ../../../third_party/skia/include/private/GrImageContext.h +FILE: ../../../third_party/skia/include/private/GrRecordingContext.h +FILE: ../../../third_party/skia/include/private/SkVx.h +FILE: ../../../third_party/skia/modules/skottie/src/text/SkottieShaper.cpp +FILE: ../../../third_party/skia/modules/skottie/src/text/SkottieShaper.h +FILE: ../../../third_party/skia/modules/skottie/src/text/TextAdapter.cpp +FILE: ../../../third_party/skia/modules/skottie/src/text/TextAdapter.h +FILE: ../../../third_party/skia/modules/skottie/src/text/TextValue.cpp +FILE: ../../../third_party/skia/modules/skottie/src/text/TextValue.h +FILE: ../../../third_party/skia/modules/sksg/include/SkSGRenderEffect.h +FILE: ../../../third_party/skia/modules/sksg/src/SkSGRenderEffect.cpp +FILE: ../../../third_party/skia/modules/sksg/src/SkSGTransformPriv.h +FILE: ../../../third_party/skia/samplecode/SampleDegenerateQuads.cpp +FILE: ../../../third_party/skia/samplecode/SampleSG.cpp +FILE: ../../../third_party/skia/samplecode/SampleThinAA.cpp +FILE: ../../../third_party/skia/src/codec/SkScalingCodec.h +FILE: ../../../third_party/skia/src/core/SkDescriptor.cpp +FILE: ../../../third_party/skia/src/core/SkEffectPriv.h +FILE: ../../../third_party/skia/src/core/SkStrikeInterface.h +FILE: ../../../third_party/skia/src/core/SkStrikeSpec.h +FILE: ../../../third_party/skia/src/gpu/GrAHardwareBufferUtils.cpp +FILE: ../../../third_party/skia/src/gpu/GrAHardwareBufferUtils.h +FILE: ../../../third_party/skia/src/gpu/GrBaseContextPriv.h +FILE: ../../../third_party/skia/src/gpu/GrBuffer.h +FILE: ../../../third_party/skia/src/gpu/GrContextPriv.cpp +FILE: ../../../third_party/skia/src/gpu/GrContextThreadSafeProxy.cpp +FILE: ../../../third_party/skia/src/gpu/GrContext_Base.cpp +FILE: ../../../third_party/skia/src/gpu/GrCpuBuffer.h +FILE: ../../../third_party/skia/src/gpu/GrGpuBuffer.cpp +FILE: ../../../third_party/skia/src/gpu/GrGpuBuffer.h +FILE: ../../../third_party/skia/src/gpu/GrImageContext.cpp +FILE: ../../../third_party/skia/src/gpu/GrImageContextPriv.h +FILE: ../../../third_party/skia/src/gpu/GrRecordingContext.cpp +FILE: ../../../third_party/skia/src/gpu/GrRecordingContextPriv.h +FILE: ../../../third_party/skia/src/gpu/GrSamplePatternDictionary.cpp +FILE: ../../../third_party/skia/src/gpu/GrSamplePatternDictionary.h +FILE: ../../../third_party/skia/src/gpu/ccpr/GrGSCoverageProcessor.h +FILE: ../../../third_party/skia/src/gpu/ccpr/GrOctoBounds.cpp +FILE: ../../../third_party/skia/src/gpu/ccpr/GrOctoBounds.h +FILE: ../../../third_party/skia/src/gpu/ccpr/GrVSCoverageProcessor.h +FILE: ../../../third_party/skia/src/gpu/effects/GrMixerEffect.fp +FILE: ../../../third_party/skia/src/gpu/effects/GrOverrideInputFragmentProcessor.fp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrMixerEffect.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrMixerEffect.h +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp +FILE: ../../../third_party/skia/src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h +FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlCommandBuffer.h +FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlCommandBuffer.mm +FILE: ../../../third_party/skia/src/gpu/mtl/GrMtlDepthStencil.h +FILE: ../../../third_party/skia/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp +FILE: ../../../third_party/skia/src/gpu/vk/GrVkSecondaryCBDrawContext.h +FILE: ../../../third_party/skia/src/sksl/SkSLDefines.h +FILE: ../../../third_party/skia/src/sksl/SkSLOutputStream.cpp +FILE: ../../../third_party/skia/src/utils/SkCharToGlyphCache.cpp +FILE: ../../../third_party/skia/src/utils/SkCharToGlyphCache.h +FILE: ../../../third_party/skia/src/utils/SkShaperJSONWriter.cpp +FILE: ../../../third_party/skia/src/utils/SkShaperJSONWriter.h ---------------------------------------------------------------------------------------------------- -Copyright 2019 Google LLC. +Copyright 2019 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -5029,19 +5677,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/gm/skbug_8664.cpp + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/gm/circles.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/gm/skbug_8664.cpp -FILE: ../../../third_party/skia/include/gpu/GrContextThreadSafeProxy.h -FILE: ../../../third_party/skia/modules/sksg/src/SkSGTransformPriv.h -FILE: ../../../third_party/skia/src/core/SkDescriptor.cpp -FILE: ../../../third_party/skia/src/gpu/GrContextThreadSafeProxy.cpp -FILE: ../../../third_party/skia/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp -FILE: ../../../third_party/skia/src/gpu/vk/GrVkSecondaryCBDrawContext.h -FILE: ../../../third_party/skia/src/sksl/SkSLDefines.h -FILE: ../../../third_party/skia/src/sksl/SkSLOutputStream.cpp +FILE: ../../../third_party/skia/gm/circles.cpp ---------------------------------------------------------------------------------------------------- -Copyright 2019 Google Inc. +Copyright 2012 Intel Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -5086,7 +5726,6 @@ FILE: ../../../third_party/skia/include/core/SkGraphics.h FILE: ../../../third_party/skia/include/core/SkMaskFilter.h FILE: ../../../third_party/skia/include/core/SkMath.h FILE: ../../../third_party/skia/include/core/SkMatrix.h -FILE: ../../../third_party/skia/include/core/SkMetaData.h FILE: ../../../third_party/skia/include/core/SkPaint.h FILE: ../../../third_party/skia/include/core/SkPath.h FILE: ../../../third_party/skia/include/core/SkPathEffect.h @@ -5116,7 +5755,6 @@ FILE: ../../../third_party/skia/include/private/SkFixed.h FILE: ../../../third_party/skia/include/private/SkFloatingPoint.h FILE: ../../../third_party/skia/include/private/SkNoncopyable.h FILE: ../../../third_party/skia/include/private/SkTDArray.h -FILE: ../../../third_party/skia/include/private/SkTSearch.h FILE: ../../../third_party/skia/include/private/SkTemplates.h FILE: ../../../third_party/skia/include/utils/SkBase64.h FILE: ../../../third_party/skia/include/utils/SkCamera.h @@ -5158,7 +5796,6 @@ FILE: ../../../third_party/skia/src/core/SkGraphics.cpp FILE: ../../../third_party/skia/src/core/SkMask.h FILE: ../../../third_party/skia/src/core/SkMaskFilter.cpp FILE: ../../../third_party/skia/src/core/SkMatrix.cpp -FILE: ../../../third_party/skia/src/core/SkMetaData.cpp FILE: ../../../third_party/skia/src/core/SkModeColorFilter.cpp FILE: ../../../third_party/skia/src/core/SkOSFile.h FILE: ../../../third_party/skia/src/core/SkPaint.cpp @@ -5186,6 +5823,7 @@ FILE: ../../../third_party/skia/src/core/SkStroke.h FILE: ../../../third_party/skia/src/core/SkStrokerPriv.cpp FILE: ../../../third_party/skia/src/core/SkStrokerPriv.h FILE: ../../../third_party/skia/src/core/SkTSearch.cpp +FILE: ../../../third_party/skia/src/core/SkTSearch.h FILE: ../../../third_party/skia/src/core/SkTSort.h FILE: ../../../third_party/skia/src/core/SkUtils.cpp FILE: ../../../third_party/skia/src/core/SkUtils.h @@ -5215,8 +5853,9 @@ FILE: ../../../third_party/skia/src/shaders/SkComposeShader.h FILE: ../../../third_party/skia/src/shaders/SkShader.cpp FILE: ../../../third_party/skia/src/shaders/gradients/SkGradientShader.cpp FILE: ../../../third_party/skia/src/utils/SkBase64.cpp -FILE: ../../../third_party/skia/src/utils/SkBase64.h FILE: ../../../third_party/skia/src/utils/SkCamera.cpp +FILE: ../../../third_party/skia/src/utils/SkMetaData.cpp +FILE: ../../../third_party/skia/src/utils/SkMetaData.h FILE: ../../../third_party/skia/src/utils/SkParse.cpp FILE: ../../../third_party/skia/src/utils/SkParseColor.cpp FILE: ../../../third_party/skia/src/xml/SkDOM.cpp @@ -5572,8 +6211,8 @@ TYPE: LicenseType.bsd FILE: ../../../third_party/skia/include/gpu/GrDriverBugWorkaroundsAutogen.h FILE: ../../../third_party/skia/include/utils/SkTraceEventPhase.h FILE: ../../../third_party/skia/infra/lottiecap/gold/lottie-web-aggregator.go -FILE: ../../../third_party/skia/infra/pathkit/gold/wasm_gold_aggregator.go -FILE: ../../../third_party/skia/infra/pathkit/perf/wasm_perf_aggregator.go +FILE: ../../../third_party/skia/infra/wasm-common/gold/wasm_gold_aggregator.go +FILE: ../../../third_party/skia/infra/wasm-common/perf/wasm_perf_aggregator.go ---------------------------------------------------------------------------------------------------- Copyright 2018 The Chromium Authors. All rights reserved. @@ -5674,6 +6313,41 @@ 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: ../../../third_party/skia/infra/bots/recipe_modules/flavor/resources/win_run_and_check_log.ps1 + ../../../LICENSE +TYPE: LicenseType.bsd +FILE: ../../../third_party/skia/infra/bots/recipe_modules/flavor/resources/win_run_and_check_log.ps1 +---------------------------------------------------------------------------------------------------- +Copyright 2019 The Chromium Authors. All rights reserved. + +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 Google Inc. 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: ../../../third_party/skia/src/codec/SkCodecPriv.h + ../../../third_party/skia/LICENSE @@ -5787,13 +6461,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/src/compute/sk/SkDevice_Compute.h + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/src/core/SkBitmapProcState_matrixProcs.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/src/compute/sk/SkDevice_Compute.h -FILE: ../../../third_party/skia/src/core/SkScan_AAAPath.cpp -FILE: ../../../third_party/skia/src/core/SkScan_DAAPath.cpp +FILE: ../../../third_party/skia/src/core/SkBitmapProcState_matrixProcs.cpp ---------------------------------------------------------------------------------------------------- -Copyright 2016 The Android Open Source Project +NEON optimized code (C) COPYRIGHT 2009 Motorola Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -5827,8 +6499,9 @@ LIBRARY: skia ORIGIN: ../../../third_party/skia/src/core/SkBitmapProcState_matrixProcs.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd FILE: ../../../third_party/skia/src/core/SkBitmapProcState_matrixProcs.cpp +FILE: ../../../third_party/skia/src/ports/SkFontMgr_FontConfigInterface_factory.cpp ---------------------------------------------------------------------------------------------------- -NEON optimized code (C) COPYRIGHT 2009 Motorola +Copyright 2008 Google Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -5859,12 +6532,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/src/core/SkBitmapProcState_matrixProcs.cpp + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/src/core/SkDevice.h + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/src/core/SkBitmapProcState_matrixProcs.cpp -FILE: ../../../third_party/skia/src/ports/SkFontMgr_FontConfigInterface_factory.cpp +FILE: ../../../third_party/skia/src/core/SkDevice.h +FILE: ../../../third_party/skia/src/core/SkScalar.cpp +FILE: ../../../third_party/skia/src/core/SkTextFormatParams.h +FILE: ../../../third_party/skia/src/images/SkJPEGWriteUtility.cpp +FILE: ../../../third_party/skia/src/images/SkJPEGWriteUtility.h +FILE: ../../../third_party/skia/src/pdf/SkDeflate.cpp +FILE: ../../../third_party/skia/src/pdf/SkDeflate.h +FILE: ../../../third_party/skia/src/pdf/SkPDFFormXObject.cpp +FILE: ../../../third_party/skia/src/pdf/SkPDFFormXObject.h +FILE: ../../../third_party/skia/src/pdf/SkPDFGraphicState.h +FILE: ../../../third_party/skia/src/pdf/SkPDFTypes.h ---------------------------------------------------------------------------------------------------- -Copyright 2008 Google Inc. +Copyright 2010 The Android Open Source Project Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -5895,21 +6577,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/src/core/SkDevice.h + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/src/core/SkGlyphRun.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/src/core/SkDevice.h -FILE: ../../../third_party/skia/src/core/SkScalar.cpp -FILE: ../../../third_party/skia/src/core/SkTextFormatParams.h -FILE: ../../../third_party/skia/src/images/SkJPEGWriteUtility.cpp -FILE: ../../../third_party/skia/src/images/SkJPEGWriteUtility.h -FILE: ../../../third_party/skia/src/pdf/SkDeflate.cpp -FILE: ../../../third_party/skia/src/pdf/SkDeflate.h -FILE: ../../../third_party/skia/src/pdf/SkPDFFormXObject.cpp -FILE: ../../../third_party/skia/src/pdf/SkPDFFormXObject.h -FILE: ../../../third_party/skia/src/pdf/SkPDFGraphicState.h -FILE: ../../../third_party/skia/src/pdf/SkPDFTypes.h +FILE: ../../../third_party/skia/src/core/SkGlyphRun.cpp +FILE: ../../../third_party/skia/src/core/SkGlyphRun.h +FILE: ../../../third_party/skia/src/core/SkGlyphRunPainter.cpp +FILE: ../../../third_party/skia/src/core/SkGlyphRunPainter.h ---------------------------------------------------------------------------------------------------- -Copyright 2010 The Android Open Source Project +Copyright 2018 The Android Open Source Project Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -5940,14 +6615,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/src/core/SkGlyphRun.cpp + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/src/core/SkMatrixImageFilter.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/src/core/SkGlyphRun.cpp -FILE: ../../../third_party/skia/src/core/SkGlyphRun.h -FILE: ../../../third_party/skia/src/core/SkGlyphRunPainter.cpp -FILE: ../../../third_party/skia/src/core/SkGlyphRunPainter.h +FILE: ../../../third_party/skia/src/core/SkMatrixImageFilter.cpp +FILE: ../../../third_party/skia/src/core/SkMatrixImageFilter.h ---------------------------------------------------------------------------------------------------- -Copyright 2018 The Android Open Source Project +Copyright 2014 The Android Open Source Project Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -5978,12 +6651,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== LIBRARY: skia -ORIGIN: ../../../third_party/skia/src/core/SkMatrixImageFilter.cpp + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/src/core/SkScan_AAAPath.cpp + ../../../third_party/skia/LICENSE TYPE: LicenseType.bsd -FILE: ../../../third_party/skia/src/core/SkMatrixImageFilter.cpp -FILE: ../../../third_party/skia/src/core/SkMatrixImageFilter.h +FILE: ../../../third_party/skia/src/core/SkScan_AAAPath.cpp ---------------------------------------------------------------------------------------------------- -Copyright 2014 The Android Open Source Project +Copyright 2016 The Android Open Source Project + +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 Google Inc. 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: ../../../third_party/skia/src/core/SkStrikeSpec.cpp + ../../../third_party/skia/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../third_party/skia/src/core/SkStrikeSpec.cpp +---------------------------------------------------------------------------------------------------- +Copyright 2019 The Android Open Source Project Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -6275,4 +6982,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ==================================================================================================== -Total license count: 56 +Total license count: 55 diff --git a/ci/licenses_golden/licenses_third_party b/ci/licenses_golden/licenses_third_party index 63057ac7e3dff..c8ce1c6ccfbea 100644 --- a/ci/licenses_golden/licenses_third_party +++ b/ci/licenses_golden/licenses_third_party @@ -1,4 +1,4 @@ -Signature: 8c93c6ef0de9e89d30fad2c99c899a75 +Signature: f5c40f80e503848dfbbc373deaa09bad UNUSED LICENSES: @@ -388,6 +388,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. LIBRARY: boringssl LIBRARY: observatory_pub_packages LIBRARY: vulkan +LIBRARY: wuffs ORIGIN: ../../../flutter/third_party/txt/LICENSE TYPE: LicenseType.apache FILE: ../../../third_party/boringssl/src/third_party/wycheproof_testvectors/METADATA @@ -514,6 +515,101 @@ FILE: ../../../third_party/vulkan/include/vulkan/vulkan_win32.h FILE: ../../../third_party/vulkan/include/vulkan/vulkan_xcb.h FILE: ../../../third_party/vulkan/include/vulkan/vulkan_xlib.h FILE: ../../../third_party/vulkan/include/vulkan/vulkan_xlib_xrandr.h +FILE: ../../../third_party/wuffs/cmd/commonflags/commonflags.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/genlib.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/all-impl.c +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/core-private.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/core-public.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/image-impl.c +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/image-private.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/image-public.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/io-private.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/io-public.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/memory-private.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/memory-public.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/range-private.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/base/range-public.h +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/builtin.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/cgen.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/data.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/expr.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/func.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/gen.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/resume.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/statement.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/internal/cgen/var.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/main.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/release.go +FILE: ../../../third_party/wuffs/cmd/wuffs-c/test.go +FILE: ../../../third_party/wuffs/cmd/wuffs/gen.go +FILE: ../../../third_party/wuffs/cmd/wuffs/main.go +FILE: ../../../third_party/wuffs/cmd/wuffs/release.go +FILE: ../../../third_party/wuffs/cmd/wuffs/test.go +FILE: ../../../third_party/wuffs/cmd/wuffsfmt/main.go +FILE: ../../../third_party/wuffs/example/crc32/crc32.cc +FILE: ../../../third_party/wuffs/example/gifplayer/gifplayer.c +FILE: ../../../third_party/wuffs/example/library/library.c +FILE: ../../../third_party/wuffs/example/zcat/zcat.c +FILE: ../../../third_party/wuffs/fuzz/c/fuzzlib/fuzzlib.c +FILE: ../../../third_party/wuffs/fuzz/c/std/gif_fuzzer.c +FILE: ../../../third_party/wuffs/fuzz/c/std/zlib_fuzzer.c +FILE: ../../../third_party/wuffs/lang/ast/ast.go +FILE: ../../../third_party/wuffs/lang/ast/eq.go +FILE: ../../../third_party/wuffs/lang/ast/sort.go +FILE: ../../../third_party/wuffs/lang/ast/string.go +FILE: ../../../third_party/wuffs/lang/ast/string_test.go +FILE: ../../../third_party/wuffs/lang/builtin/builtin.go +FILE: ../../../third_party/wuffs/lang/check/assert.go +FILE: ../../../third_party/wuffs/lang/check/bounds.go +FILE: ../../../third_party/wuffs/lang/check/check.go +FILE: ../../../third_party/wuffs/lang/check/check_test.go +FILE: ../../../third_party/wuffs/lang/check/data.go +FILE: ../../../third_party/wuffs/lang/check/gen.go +FILE: ../../../third_party/wuffs/lang/check/optimize.go +FILE: ../../../third_party/wuffs/lang/check/resolve.go +FILE: ../../../third_party/wuffs/lang/check/type.go +FILE: ../../../third_party/wuffs/lang/generate/generate.go +FILE: ../../../third_party/wuffs/lang/parse/parse.go +FILE: ../../../third_party/wuffs/lang/render/render.go +FILE: ../../../third_party/wuffs/lang/token/list.go +FILE: ../../../third_party/wuffs/lang/token/token.go +FILE: ../../../third_party/wuffs/lang/wuffsroot/wuffsroot.go +FILE: ../../../third_party/wuffs/lib/base38/base38.go +FILE: ../../../third_party/wuffs/lib/base38/base38_test.go +FILE: ../../../third_party/wuffs/lib/interval/interval.go +FILE: ../../../third_party/wuffs/lib/interval/interval_test.go +FILE: ../../../third_party/wuffs/lib/interval/radial_test.go +FILE: ../../../third_party/wuffs/release/c/wuffs-unsupported-snapshot.c +FILE: ../../../third_party/wuffs/release/c/wuffs-v0.2.c +FILE: ../../../third_party/wuffs/script/adler32-standalone.c +FILE: ../../../third_party/wuffs/script/bench-c-deflate-fragmentation.c +FILE: ../../../third_party/wuffs/script/bench-go-gif/main.go +FILE: ../../../third_party/wuffs/script/bench-rust-gif-dot-rs/src/main.rs +FILE: ../../../third_party/wuffs/script/bench-rust-gif/src/main.rs +FILE: ../../../third_party/wuffs/script/checksum.go +FILE: ../../../third_party/wuffs/script/compress-giflzw.go +FILE: ../../../third_party/wuffs/script/crawl.go +FILE: ../../../third_party/wuffs/script/extract-deflate-offsets.go +FILE: ../../../third_party/wuffs/script/extract-giflzw.go +FILE: ../../../third_party/wuffs/script/extract-palette-indexes.go +FILE: ../../../third_party/wuffs/script/inline-c-relative-includes.go +FILE: ../../../third_party/wuffs/script/make-artificial.go +FILE: ../../../third_party/wuffs/script/print-bits.go +FILE: ../../../third_party/wuffs/script/print-crc32-example.go +FILE: ../../../third_party/wuffs/script/print-crc32-magic-numbers.go +FILE: ../../../third_party/wuffs/script/print-deflate-magic-numbers.go +FILE: ../../../third_party/wuffs/script/print-lzw-example.go +FILE: ../../../third_party/wuffs/script/wuffs-deflate-decoder-decode-huffman.c +FILE: ../../../third_party/wuffs/std/adler32/common_adler32.wuffs +FILE: ../../../third_party/wuffs/std/crc32/common_crc32.wuffs +FILE: ../../../third_party/wuffs/std/deflate/common_consts.wuffs +FILE: ../../../third_party/wuffs/std/deflate/decode_deflate.wuffs +FILE: ../../../third_party/wuffs/std/deflate/decode_huffman_fast.wuffs +FILE: ../../../third_party/wuffs/std/deflate/decode_huffman_slow.wuffs +FILE: ../../../third_party/wuffs/std/gif/decode_gif.wuffs +FILE: ../../../third_party/wuffs/std/gzip/decode_gzip.wuffs +FILE: ../../../third_party/wuffs/std/lzw/decode_lzw.wuffs +FILE: ../../../third_party/wuffs/std/zlib/decode_zlib.wuffs ---------------------------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 @@ -4512,7 +4608,9 @@ FILE: ../../../third_party/dart/runtime/observatory/web/favicon.ico FILE: ../../../third_party/dart/runtime/observatory/web/index.html FILE: ../../../third_party/dart/runtime/observatory/web/third_party/trace_viewer_full.html FILE: ../../../third_party/dart/runtime/observatory/web/timeline.html -FILE: ../../../third_party/dart/runtime/vm/snapshot_test_in.dat +FILE: ../../../third_party/dart/runtime/vm/compiler/ffi_dbc_trampoline_x64_linux_mac.S +FILE: ../../../third_party/dart/samples/ffi/sqlite/docs/lib/scenario-default.svg +FILE: ../../../third_party/dart/samples/ffi/sqlite/docs/lib/scenario-full.svg FILE: ../../../third_party/dart/sdk/lib/html/html_common/conversions_dart2js.dart FILE: ../../../third_party/dart/sdk/lib/html/html_common/html_common.dart FILE: ../../../third_party/dart/sdk/lib/libraries.json @@ -4609,11 +4707,6 @@ FILE: ../../../third_party/dart/runtime/bin/io_buffer.h FILE: ../../../third_party/dart/runtime/bin/io_natives.h FILE: ../../../third_party/dart/runtime/bin/isolate_data.h FILE: ../../../third_party/dart/runtime/bin/lockers.h -FILE: ../../../third_party/dart/runtime/bin/log.h -FILE: ../../../third_party/dart/runtime/bin/log_android.cc -FILE: ../../../third_party/dart/runtime/bin/log_linux.cc -FILE: ../../../third_party/dart/runtime/bin/log_macos.cc -FILE: ../../../third_party/dart/runtime/bin/log_win.cc FILE: ../../../third_party/dart/runtime/bin/main.cc FILE: ../../../third_party/dart/runtime/bin/platform.cc FILE: ../../../third_party/dart/runtime/bin/platform.h @@ -4631,7 +4724,6 @@ FILE: ../../../third_party/dart/runtime/bin/run_vm_tests.cc FILE: ../../../third_party/dart/runtime/bin/secure_socket_patch.dart FILE: ../../../third_party/dart/runtime/bin/secure_socket_unsupported.cc FILE: ../../../third_party/dart/runtime/bin/socket_android.cc -FILE: ../../../third_party/dart/runtime/bin/socket_base_android.cc FILE: ../../../third_party/dart/runtime/bin/socket_base_android.h FILE: ../../../third_party/dart/runtime/bin/socket_base_linux.h FILE: ../../../third_party/dart/runtime/bin/socket_base_macos.h @@ -4705,8 +4797,15 @@ FILE: ../../../third_party/dart/runtime/platform/floating_point_win.h FILE: ../../../third_party/dart/runtime/platform/globals.h FILE: ../../../third_party/dart/runtime/platform/hashmap.cc FILE: ../../../third_party/dart/runtime/platform/hashmap.h +FILE: ../../../third_party/dart/runtime/platform/syslog.h +FILE: ../../../third_party/dart/runtime/platform/syslog_android.cc +FILE: ../../../third_party/dart/runtime/platform/syslog_linux.cc +FILE: ../../../third_party/dart/runtime/platform/syslog_macos.cc +FILE: ../../../third_party/dart/runtime/platform/syslog_win.cc FILE: ../../../third_party/dart/runtime/platform/text_buffer.cc FILE: ../../../third_party/dart/runtime/platform/text_buffer.h +FILE: ../../../third_party/dart/runtime/platform/unicode.cc +FILE: ../../../third_party/dart/runtime/platform/unicode.h FILE: ../../../third_party/dart/runtime/platform/utils.cc FILE: ../../../third_party/dart/runtime/platform/utils.h FILE: ../../../third_party/dart/runtime/platform/utils_android.cc @@ -4872,7 +4971,6 @@ FILE: ../../../third_party/dart/runtime/vm/snapshot.cc FILE: ../../../third_party/dart/runtime/vm/snapshot.h FILE: ../../../third_party/dart/runtime/vm/snapshot_ids.h FILE: ../../../third_party/dart/runtime/vm/snapshot_test.cc -FILE: ../../../third_party/dart/runtime/vm/snapshot_test.dart FILE: ../../../third_party/dart/runtime/vm/stack_frame.cc FILE: ../../../third_party/dart/runtime/vm/stack_frame_test.cc FILE: ../../../third_party/dart/runtime/vm/stub_code.cc @@ -4884,7 +4982,6 @@ FILE: ../../../third_party/dart/runtime/vm/thread_pool_test.cc FILE: ../../../third_party/dart/runtime/vm/thread_test.cc FILE: ../../../third_party/dart/runtime/vm/token.h FILE: ../../../third_party/dart/runtime/vm/unicode.cc -FILE: ../../../third_party/dart/runtime/vm/unicode.h FILE: ../../../third_party/dart/runtime/vm/unit_test.cc FILE: ../../../third_party/dart/runtime/vm/utils_test.cc FILE: ../../../third_party/dart/runtime/vm/version.h @@ -5023,6 +5120,140 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== +==================================================================================================== +LIBRARY: dart +ORIGIN: ../../../third_party/dart/runtime/bin/abi_version.h + ../../../third_party/dart/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../third_party/dart/runtime/bin/abi_version.h +FILE: ../../../third_party/dart/runtime/bin/abi_version_in.cc +FILE: ../../../third_party/dart/runtime/bin/entrypoints_verification_test_extension.cc +FILE: ../../../third_party/dart/runtime/bin/entrypoints_verification_test_extension_dllmain_win.cc +FILE: ../../../third_party/dart/runtime/bin/ffi_test_dynamic_library.cc +FILE: ../../../third_party/dart/runtime/bin/ffi_test_functions.cc +FILE: ../../../third_party/dart/runtime/bin/ifaddrs-android.cc +FILE: ../../../third_party/dart/runtime/bin/ifaddrs-android.h +FILE: ../../../third_party/dart/runtime/bin/namespace_fuchsia.h +FILE: ../../../third_party/dart/runtime/bin/socket_base_android.cc +FILE: ../../../third_party/dart/runtime/lib/ffi.cc +FILE: ../../../third_party/dart/runtime/lib/ffi.h +FILE: ../../../third_party/dart/runtime/lib/ffi_dynamic_library.cc +FILE: ../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart +FILE: ../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart +FILE: ../../../third_party/dart/runtime/lib/ffi_patch.dart +FILE: ../../../third_party/dart/runtime/tools/dartfuzz/dartfuzz_api_table.dart +FILE: ../../../third_party/dart/runtime/tools/dartfuzz/gen_api_table.dart +FILE: ../../../third_party/dart/runtime/tools/graphexplorer/graphexplorer.html +FILE: ../../../third_party/dart/runtime/tools/graphexplorer/graphexplorer.js +FILE: ../../../third_party/dart/runtime/vm/catch_entry_moves_test.cc +FILE: ../../../third_party/dart/runtime/vm/class_id.h +FILE: ../../../third_party/dart/runtime/vm/code_entry_kind.h +FILE: ../../../third_party/dart/runtime/vm/compiler/asm_intrinsifier.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/asm_intrinsifier.h +FILE: ../../../third_party/dart/runtime/vm/compiler/asm_intrinsifier_arm.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/asm_intrinsifier_arm64.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/asm_intrinsifier_ia32.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/asm_intrinsifier_x64.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/block_builder.h +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/flow_graph_checker.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/flow_graph_checker.h +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/il_test_helper.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/il_test_helper.h +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/slot_test.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/type_propagator_test.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/typed_data_aot_test.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/ffi.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/ffi.h +FILE: ../../../third_party/dart/runtime/vm/compiler/ffi_dbc_trampoline.h +FILE: ../../../third_party/dart/runtime/vm/compiler/graph_intrinsifier.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/graph_intrinsifier.h +FILE: ../../../third_party/dart/runtime/vm/compiler/graph_intrinsifier_arm.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/graph_intrinsifier_arm64.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/graph_intrinsifier_ia32.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/graph_intrinsifier_x64.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/recognized_methods_list.h +FILE: ../../../third_party/dart/runtime/vm/compiler/relocation.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/runtime_api.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/runtime_api.h +FILE: ../../../third_party/dart/runtime/vm/compiler/stub_code_compiler.h +FILE: ../../../third_party/dart/runtime/vm/compiler/stub_code_compiler_arm.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/stub_code_compiler_arm64.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/stub_code_compiler_dbc.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/stub_code_compiler_ia32.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/stub_code_compiler_x64.cc +FILE: ../../../third_party/dart/runtime/vm/constants_arm.cc +FILE: ../../../third_party/dart/runtime/vm/constants_arm64.cc +FILE: ../../../third_party/dart/runtime/vm/constants_dbc.cc +FILE: ../../../third_party/dart/runtime/vm/constants_ia32.cc +FILE: ../../../third_party/dart/runtime/vm/constants_kbc.cc +FILE: ../../../third_party/dart/runtime/vm/constants_x64.cc +FILE: ../../../third_party/dart/runtime/vm/frame_layout.h +FILE: ../../../third_party/dart/runtime/vm/intrusive_dlist.h +FILE: ../../../third_party/dart/runtime/vm/intrusive_dlist_test.cc +FILE: ../../../third_party/dart/runtime/vm/libfuzzer/dart_libfuzzer.cc +FILE: ../../../third_party/dart/runtime/vm/longjump.h +FILE: ../../../third_party/dart/runtime/vm/pointer_tagging.h +FILE: ../../../third_party/dart/runtime/vm/splay-tree.h +FILE: ../../../third_party/dart/runtime/vm/static_type_exactness_state.h +FILE: ../../../third_party/dart/runtime/vm/stub_code_list.h +FILE: ../../../third_party/dart/runtime/vm/thread_stack_resource.cc +FILE: ../../../third_party/dart/runtime/vm/thread_stack_resource.h +FILE: ../../../third_party/dart/runtime/vm/thread_state.cc +FILE: ../../../third_party/dart/runtime/vm/thread_state.h +FILE: ../../../third_party/dart/runtime/vm/type_testing_stubs_arm.cc +FILE: ../../../third_party/dart/runtime/vm/type_testing_stubs_arm64.cc +FILE: ../../../third_party/dart/runtime/vm/type_testing_stubs_x64.cc +FILE: ../../../third_party/dart/samples/ffi/coordinate.dart +FILE: ../../../third_party/dart/samples/ffi/dylib_utils.dart +FILE: ../../../third_party/dart/samples/ffi/sample_ffi_data.dart +FILE: ../../../third_party/dart/samples/ffi/sample_ffi_dynamic_library.dart +FILE: ../../../third_party/dart/samples/ffi/sample_ffi_functions.dart +FILE: ../../../third_party/dart/samples/ffi/sample_ffi_functions_callbacks.dart +FILE: ../../../third_party/dart/samples/ffi/sample_ffi_functions_structs.dart +FILE: ../../../third_party/dart/samples/ffi/sample_ffi_structs.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/example/main.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/sqlite.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/bindings/bindings.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/bindings/constants.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/bindings/signatures.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/bindings/types.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/collections/closable_iterator.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/database.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/ffi/arena.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/ffi/cstring.dart +FILE: ../../../third_party/dart/samples/ffi/sqlite/lib/src/ffi/dylib_utils.dart +FILE: ../../../third_party/dart/sdk/lib/ffi/annotations.dart +FILE: ../../../third_party/dart/sdk/lib/ffi/dynamic_library.dart +FILE: ../../../third_party/dart/sdk/lib/ffi/ffi.dart +FILE: ../../../third_party/dart/sdk/lib/ffi/native_type.dart +---------------------------------------------------------------------------------------------------- +Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +for details. All rights reserved. + +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 Google Inc. 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: dart ORIGIN: ../../../third_party/dart/runtime/bin/cli.cc + ../../../third_party/dart/LICENSE @@ -5134,7 +5365,6 @@ FILE: ../../../third_party/dart/runtime/vm/malloc_hooks.h FILE: ../../../third_party/dart/runtime/vm/malloc_hooks_arm.cc FILE: ../../../third_party/dart/runtime/vm/malloc_hooks_arm64.cc FILE: ../../../third_party/dart/runtime/vm/malloc_hooks_ia32.cc -FILE: ../../../third_party/dart/runtime/vm/malloc_hooks_jemalloc.cc FILE: ../../../third_party/dart/runtime/vm/malloc_hooks_tcmalloc.cc FILE: ../../../third_party/dart/runtime/vm/malloc_hooks_test.cc FILE: ../../../third_party/dart/runtime/vm/malloc_hooks_unsupported.cc @@ -5249,6 +5479,7 @@ FILE: ../../../third_party/dart/runtime/vm/compiler/backend/compile_type.h FILE: ../../../third_party/dart/runtime/vm/compiler/backend/loops.cc FILE: ../../../third_party/dart/runtime/vm/compiler/backend/loops.h FILE: ../../../third_party/dart/runtime/vm/compiler/backend/loops_test.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/backend/redundancy_elimination_test.cc FILE: ../../../third_party/dart/runtime/vm/compiler/backend/slot.cc FILE: ../../../third_party/dart/runtime/vm/compiler/backend/slot.h FILE: ../../../third_party/dart/runtime/vm/compiler/compiler_pass.cc @@ -5261,6 +5492,7 @@ FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/bytecode_flow_graph FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/bytecode_reader.cc FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/bytecode_reader.h +FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/bytecode_scope_builder.cc FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/constant_evaluator.cc FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/constant_evaluator.h FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/kernel_fingerprints.cc @@ -5338,7 +5570,6 @@ FILE: ../../../third_party/dart/runtime/bin/file_support.cc FILE: ../../../third_party/dart/runtime/bin/file_system_watcher_fuchsia.cc FILE: ../../../third_party/dart/runtime/bin/loader.cc FILE: ../../../third_party/dart/runtime/bin/loader.h -FILE: ../../../third_party/dart/runtime/bin/log_fuchsia.cc FILE: ../../../third_party/dart/runtime/bin/platform_fuchsia.cc FILE: ../../../third_party/dart/runtime/bin/process_fuchsia.cc FILE: ../../../third_party/dart/runtime/bin/reference_counting.h @@ -5503,11 +5734,13 @@ FILE: ../../../third_party/dart/runtime/observatory/lib/src/repositories/top_ret FILE: ../../../third_party/dart/runtime/observatory/lib/src/repositories/type_arguments.dart FILE: ../../../third_party/dart/runtime/observatory/web/timeline_message_handler.js FILE: ../../../third_party/dart/runtime/platform/atomic_fuchsia.h +FILE: ../../../third_party/dart/runtime/platform/syslog_fuchsia.cc FILE: ../../../third_party/dart/runtime/platform/utils_fuchsia.cc FILE: ../../../third_party/dart/runtime/platform/utils_fuchsia.h FILE: ../../../third_party/dart/runtime/vm/clustered_snapshot.cc FILE: ../../../third_party/dart/runtime/vm/clustered_snapshot.h FILE: ../../../third_party/dart/runtime/vm/code_patcher_dbc.cc +FILE: ../../../third_party/dart/runtime/vm/compiler/asm_intrinsifier_dbc.cc FILE: ../../../third_party/dart/runtime/vm/compiler/assembler/assembler_dbc.cc FILE: ../../../third_party/dart/runtime/vm/compiler/assembler/assembler_dbc.h FILE: ../../../third_party/dart/runtime/vm/compiler/assembler/assembler_dbc_test.cc @@ -5521,7 +5754,6 @@ FILE: ../../../third_party/dart/runtime/vm/compiler/backend/redundancy_eliminati FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/kernel_to_il.cc FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/kernel_to_il.h -FILE: ../../../third_party/dart/runtime/vm/compiler/intrinsifier_dbc.cc FILE: ../../../third_party/dart/runtime/vm/constants_dbc.h FILE: ../../../third_party/dart/runtime/vm/cpu_dbc.cc FILE: ../../../third_party/dart/runtime/vm/cpu_dbc.h @@ -5557,7 +5789,6 @@ FILE: ../../../third_party/dart/runtime/vm/signal_handler_fuchsia.cc FILE: ../../../third_party/dart/runtime/vm/simulator_dbc.cc FILE: ../../../third_party/dart/runtime/vm/simulator_dbc.h FILE: ../../../third_party/dart/runtime/vm/stack_frame_dbc.h -FILE: ../../../third_party/dart/runtime/vm/stub_code_dbc.cc FILE: ../../../third_party/dart/runtime/vm/thread_interrupter_fuchsia.cc FILE: ../../../third_party/dart/runtime/vm/token_position.cc FILE: ../../../third_party/dart/runtime/vm/token_position.h @@ -5598,59 +5829,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== -==================================================================================================== -LIBRARY: dart -ORIGIN: ../../../third_party/dart/runtime/bin/entrypoints_verification_test_extension.cc + ../../../third_party/dart/LICENSE -TYPE: LicenseType.bsd -FILE: ../../../third_party/dart/runtime/bin/entrypoints_verification_test_extension.cc -FILE: ../../../third_party/dart/runtime/bin/entrypoints_verification_test_extension_dllmain_win.cc -FILE: ../../../third_party/dart/runtime/bin/namespace_fuchsia.h -FILE: ../../../third_party/dart/runtime/vm/class_id.h -FILE: ../../../third_party/dart/runtime/vm/code_entry_kind.h -FILE: ../../../third_party/dart/runtime/vm/compiler/backend/flow_graph_checker.cc -FILE: ../../../third_party/dart/runtime/vm/compiler/backend/flow_graph_checker.h -FILE: ../../../third_party/dart/runtime/vm/compiler/backend/slot_test.cc -FILE: ../../../third_party/dart/runtime/vm/compiler/relocation.cc -FILE: ../../../third_party/dart/runtime/vm/compiler/runtime_api.cc -FILE: ../../../third_party/dart/runtime/vm/compiler/runtime_api.h -FILE: ../../../third_party/dart/runtime/vm/frame_layout.h -FILE: ../../../third_party/dart/runtime/vm/intrusive_dlist.h -FILE: ../../../third_party/dart/runtime/vm/intrusive_dlist_test.cc -FILE: ../../../third_party/dart/runtime/vm/longjump.h -FILE: ../../../third_party/dart/runtime/vm/pointer_tagging.h -FILE: ../../../third_party/dart/runtime/vm/thread_stack_resource.cc -FILE: ../../../third_party/dart/runtime/vm/thread_stack_resource.h -FILE: ../../../third_party/dart/runtime/vm/thread_state.cc -FILE: ../../../third_party/dart/runtime/vm/thread_state.h ----------------------------------------------------------------------------------------------------- -Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -for details. All rights reserved. - -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 Google Inc. 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: dart ORIGIN: ../../../third_party/dart/runtime/bin/process_test.cc + ../../../third_party/dart/LICENSE @@ -6049,9 +6227,6 @@ FILE: ../../../third_party/dart/runtime/vm/compiler/backend/locations.cc FILE: ../../../third_party/dart/runtime/vm/compiler/backend/locations.h FILE: ../../../third_party/dart/runtime/vm/compiler/backend/type_propagator.cc FILE: ../../../third_party/dart/runtime/vm/compiler/backend/type_propagator.h -FILE: ../../../third_party/dart/runtime/vm/compiler/intrinsifier_arm.cc -FILE: ../../../third_party/dart/runtime/vm/compiler/intrinsifier_ia32.cc -FILE: ../../../third_party/dart/runtime/vm/compiler/intrinsifier_x64.cc FILE: ../../../third_party/dart/runtime/vm/compiler/jit/jit_call_specializer.cc FILE: ../../../third_party/dart/runtime/vm/constants_arm.h FILE: ../../../third_party/dart/runtime/vm/constants_ia32.h @@ -6105,10 +6280,7 @@ FILE: ../../../third_party/dart/runtime/vm/simulator_arm.h FILE: ../../../third_party/dart/runtime/vm/stack_frame_arm.h FILE: ../../../third_party/dart/runtime/vm/stack_frame_ia32.h FILE: ../../../third_party/dart/runtime/vm/stack_frame_x64.h -FILE: ../../../third_party/dart/runtime/vm/stub_code_arm.cc FILE: ../../../third_party/dart/runtime/vm/stub_code_arm_test.cc -FILE: ../../../third_party/dart/runtime/vm/stub_code_ia32.cc -FILE: ../../../third_party/dart/runtime/vm/stub_code_x64.cc FILE: ../../../third_party/dart/runtime/vm/tags.h FILE: ../../../third_party/dart/runtime/vm/thread_interrupter.cc FILE: ../../../third_party/dart/runtime/vm/thread_interrupter.h @@ -6319,7 +6491,6 @@ FILE: ../../../third_party/dart/runtime/vm/compiler/backend/il_arm64.cc FILE: ../../../third_party/dart/runtime/vm/compiler/backend/range_analysis.cc FILE: ../../../third_party/dart/runtime/vm/compiler/backend/range_analysis.h FILE: ../../../third_party/dart/runtime/vm/compiler/backend/range_analysis_test.cc -FILE: ../../../third_party/dart/runtime/vm/compiler/intrinsifier_arm64.cc FILE: ../../../third_party/dart/runtime/vm/compiler/method_recognizer.cc FILE: ../../../third_party/dart/runtime/vm/compiler/method_recognizer.h FILE: ../../../third_party/dart/runtime/vm/constants_arm64.h @@ -6370,7 +6541,6 @@ FILE: ../../../third_party/dart/runtime/vm/runtime_entry_arm64.cc FILE: ../../../third_party/dart/runtime/vm/simulator_arm64.cc FILE: ../../../third_party/dart/runtime/vm/simulator_arm64.h FILE: ../../../third_party/dart/runtime/vm/stack_frame_arm64.h -FILE: ../../../third_party/dart/runtime/vm/stub_code_arm64.cc FILE: ../../../third_party/dart/runtime/vm/stub_code_arm64_test.cc FILE: ../../../third_party/dart/runtime/vm/tags.cc FILE: ../../../third_party/dart/runtime/vm/unibrow-inl.h @@ -6415,6 +6585,75 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== +==================================================================================================== +LIBRARY: dart +ORIGIN: ../../../third_party/dart/runtime/platform/splay-tree-inl.h + ../../../third_party/dart/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../third_party/dart/runtime/platform/splay-tree-inl.h +FILE: ../../../third_party/dart/runtime/platform/splay-tree.h +---------------------------------------------------------------------------------------------------- +Copyright (c) 2010, the Dart project authors. Please see the AUTHORS file +for details. All rights reserved. + +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 Google Inc. 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: dart +ORIGIN: ../../../third_party/dart/runtime/vm/compiler/frontend/bytecode_scope_builder.h + ../../../third_party/dart/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/bytecode_scope_builder.h +---------------------------------------------------------------------------------------------------- +Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +for details. All rights reserved. + +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 Google Inc. 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: double-conversion LIBRARY: icu @@ -7787,44 +8026,342 @@ documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +==================================================================================================== + +==================================================================================================== +LIBRARY: freetype2 +ORIGIN: ../../../third_party/freetype2/src/pcf/pcfutil.h +TYPE: LicenseType.mit +FILE: ../../../third_party/freetype2/src/pcf/pcfutil.h +---------------------------------------------------------------------------------------------------- +Copyright 2000, 2001, 2004 by +Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +==================================================================================================== + +==================================================================================================== +LIBRARY: glfw +ORIGIN: ../../../third_party/glfw/COPYING.txt +TYPE: LicenseType.zlib +FILE: ../../../third_party/glfw/.appveyor.yml +FILE: ../../../third_party/glfw/CMake/MacOSXBundleInfo.plist.in +FILE: ../../../third_party/glfw/cmake_uninstall.cmake.in +FILE: ../../../third_party/glfw/docs/Doxyfile.in +FILE: ../../../third_party/glfw/docs/DoxygenLayout.xml +FILE: ../../../third_party/glfw/docs/build.dox +FILE: ../../../third_party/glfw/docs/compat.dox +FILE: ../../../third_party/glfw/docs/compile.dox +FILE: ../../../third_party/glfw/docs/context.dox +FILE: ../../../third_party/glfw/docs/extra.less +FILE: ../../../third_party/glfw/docs/footer.html +FILE: ../../../third_party/glfw/docs/header.html +FILE: ../../../third_party/glfw/docs/input.dox +FILE: ../../../third_party/glfw/docs/internal.dox +FILE: ../../../third_party/glfw/docs/intro.dox +FILE: ../../../third_party/glfw/docs/main.dox +FILE: ../../../third_party/glfw/docs/monitor.dox +FILE: ../../../third_party/glfw/docs/moving.dox +FILE: ../../../third_party/glfw/docs/news.dox +FILE: ../../../third_party/glfw/docs/quick.dox +FILE: ../../../third_party/glfw/docs/spaces.svg +FILE: ../../../third_party/glfw/docs/vulkan.dox +FILE: ../../../third_party/glfw/docs/window.dox +FILE: ../../../third_party/glfw/include/GLFW/glfw3.h +FILE: ../../../third_party/glfw/include/GLFW/glfw3native.h +FILE: ../../../third_party/glfw/src/cocoa_monitor.m +FILE: ../../../third_party/glfw/src/context.c +FILE: ../../../third_party/glfw/src/egl_context.c +FILE: ../../../third_party/glfw/src/egl_context.h +FILE: ../../../third_party/glfw/src/glfw3.pc.in +FILE: ../../../third_party/glfw/src/glfw3Config.cmake.in +FILE: ../../../third_party/glfw/src/glx_context.c +FILE: ../../../third_party/glfw/src/glx_context.h +FILE: ../../../third_party/glfw/src/init.c +FILE: ../../../third_party/glfw/src/input.c +FILE: ../../../third_party/glfw/src/internal.h +FILE: ../../../third_party/glfw/src/linux_joystick.c +FILE: ../../../third_party/glfw/src/monitor.c +FILE: ../../../third_party/glfw/src/posix_time.c +FILE: ../../../third_party/glfw/src/posix_time.h +FILE: ../../../third_party/glfw/src/posix_tls.c +FILE: ../../../third_party/glfw/src/posix_tls.h +FILE: ../../../third_party/glfw/src/vulkan.c +FILE: ../../../third_party/glfw/src/wgl_context.c +FILE: ../../../third_party/glfw/src/wgl_context.h +FILE: ../../../third_party/glfw/src/win32_init.c +FILE: ../../../third_party/glfw/src/win32_joystick.c +FILE: ../../../third_party/glfw/src/win32_monitor.c +FILE: ../../../third_party/glfw/src/win32_platform.h +FILE: ../../../third_party/glfw/src/win32_time.c +FILE: ../../../third_party/glfw/src/win32_tls.c +FILE: ../../../third_party/glfw/src/win32_window.c +FILE: ../../../third_party/glfw/src/x11_init.c +FILE: ../../../third_party/glfw/src/x11_monitor.c +FILE: ../../../third_party/glfw/src/x11_platform.h +FILE: ../../../third_party/glfw/src/x11_window.c +FILE: ../../../third_party/glfw/src/xkb_unicode.c +---------------------------------------------------------------------------------------------------- +Copyright (c) 2002-2006 Marcus Geelnard +Copyright (c) 2006-2016 Camilla Berglund + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. +==================================================================================================== + +==================================================================================================== +LIBRARY: glfw +ORIGIN: ../../../third_party/glfw/src/cocoa_init.m +TYPE: LicenseType.zlib +FILE: ../../../third_party/glfw/src/cocoa_init.m +FILE: ../../../third_party/glfw/src/cocoa_platform.h +FILE: ../../../third_party/glfw/src/cocoa_time.c +FILE: ../../../third_party/glfw/src/cocoa_window.m +FILE: ../../../third_party/glfw/src/nsgl_context.h +FILE: ../../../third_party/glfw/src/nsgl_context.m +---------------------------------------------------------------------------------------------------- +Copyright (c) 2009-2016 Camilla Berglund + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. +==================================================================================================== + +==================================================================================================== +LIBRARY: glfw +ORIGIN: ../../../third_party/glfw/src/cocoa_joystick.h +TYPE: LicenseType.zlib +FILE: ../../../third_party/glfw/src/cocoa_joystick.h +FILE: ../../../third_party/glfw/src/win32_joystick.h +---------------------------------------------------------------------------------------------------- +Copyright (c) 2006-2016 Camilla Berglund + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. +==================================================================================================== + +==================================================================================================== +LIBRARY: glfw +ORIGIN: ../../../third_party/glfw/src/cocoa_joystick.m +TYPE: LicenseType.zlib +FILE: ../../../third_party/glfw/src/cocoa_joystick.m +---------------------------------------------------------------------------------------------------- +Copyright (c) 2009-2016 Camilla Berglund +Copyright (c) 2012 Torsten Walluhn + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. +==================================================================================================== + +==================================================================================================== +LIBRARY: glfw +ORIGIN: ../../../third_party/glfw/src/glfw_config.h.in +TYPE: LicenseType.zlib +FILE: ../../../third_party/glfw/src/glfw_config.h.in +---------------------------------------------------------------------------------------------------- +Copyright (c) 2010-2016 Camilla Berglund + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. +==================================================================================================== + +==================================================================================================== +LIBRARY: glfw +ORIGIN: ../../../third_party/glfw/src/linux_joystick.h +TYPE: LicenseType.zlib +FILE: ../../../third_party/glfw/src/linux_joystick.h +FILE: ../../../third_party/glfw/src/wl_init.c +FILE: ../../../third_party/glfw/src/wl_monitor.c +FILE: ../../../third_party/glfw/src/wl_platform.h +FILE: ../../../third_party/glfw/src/wl_window.c +FILE: ../../../third_party/glfw/src/xkb_unicode.h +---------------------------------------------------------------------------------------------------- +Copyright (c) 2014 Jonas Ådahl + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. +==================================================================================================== + +==================================================================================================== +LIBRARY: glfw +ORIGIN: ../../../third_party/glfw/src/mir_init.c +TYPE: LicenseType.zlib +FILE: ../../../third_party/glfw/src/mir_init.c +FILE: ../../../third_party/glfw/src/mir_monitor.c +FILE: ../../../third_party/glfw/src/mir_platform.h +FILE: ../../../third_party/glfw/src/mir_window.c +---------------------------------------------------------------------------------------------------- +Copyright (c) 2014-2015 Brandon Schaefer + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. +3. This notice may not be removed or altered from any source + distribution. ==================================================================================================== ==================================================================================================== -LIBRARY: freetype2 -ORIGIN: ../../../third_party/freetype2/src/pcf/pcfutil.h -TYPE: LicenseType.mit -FILE: ../../../third_party/freetype2/src/pcf/pcfutil.h +LIBRARY: glfw +ORIGIN: ../../../third_party/glfw/src/window.c +TYPE: LicenseType.zlib +FILE: ../../../third_party/glfw/src/window.c ---------------------------------------------------------------------------------------------------- -Copyright 2000, 2001, 2004 by -Francesco Zappa Nardelli +Copyright (c) 2002-2006 Marcus Geelnard +Copyright (c) 2006-2016 Camilla Berglund +Copyright (c) 2012 Torsten Walluhn -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would + be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. ==================================================================================================== ==================================================================================================== @@ -17565,6 +18102,41 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== +==================================================================================================== +LIBRARY: tonic +ORIGIN: ../../../fuchsia/sdk/linux/LICENSE +TYPE: LicenseType.bsd +FILE: ../../../third_party/tonic/typed_data/typed_list.cc +---------------------------------------------------------------------------------------------------- +Copyright 2019 The Fuchsia Authors. All rights reserved. + +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 Google Inc. 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: tonic ORIGIN: ../../../third_party/tonic/LICENSE @@ -17594,6 +18166,8 @@ FILE: ../../../third_party/tonic/scopes/dart_isolate_scope.cc FILE: ../../../third_party/tonic/scopes/dart_isolate_scope.h FILE: ../../../third_party/tonic/typed_data/dart_byte_data.h FILE: ../../../third_party/tonic/typed_data/int32_list.h +FILE: ../../../third_party/tonic/typed_data/typed_list.h +FILE: ../../../third_party/tonic/typed_data/uint16_list.h FILE: ../../../third_party/tonic/typed_data/uint8_list.h ---------------------------------------------------------------------------------------------------- Copyright 2016 The Fuchsia Authors. All rights reserved. @@ -17726,12 +18300,8 @@ FILE: ../../../third_party/tonic/dart_wrappable.cc FILE: ../../../third_party/tonic/dart_wrappable.h FILE: ../../../third_party/tonic/dart_wrapper_info.h FILE: ../../../third_party/tonic/typed_data/dart_byte_data.cc -FILE: ../../../third_party/tonic/typed_data/float32_list.cc FILE: ../../../third_party/tonic/typed_data/float32_list.h -FILE: ../../../third_party/tonic/typed_data/float64_list.cc FILE: ../../../third_party/tonic/typed_data/float64_list.h -FILE: ../../../third_party/tonic/typed_data/int32_list.cc -FILE: ../../../third_party/tonic/typed_data/uint8_list.cc ---------------------------------------------------------------------------------------------------- Copyright 2015 The Fuchsia Authors. All rights reserved. @@ -17762,6 +18332,191 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================================================== +==================================================================================================== +LIBRARY: wuffs +ORIGIN: ../../../third_party/wuffs/LICENSE +TYPE: LicenseType.apache +FILE: ../../../third_party/wuffs/script/bench-rust-gif-dot-rs/Cargo.toml +FILE: ../../../third_party/wuffs/script/bench-rust-gif/Cargo.toml +---------------------------------------------------------------------------------------------------- +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS +==================================================================================================== + ==================================================================================================== LIBRARY: zlib ORIGIN: ../../../third_party/zlib/LICENSE @@ -18497,4 +19252,4 @@ freely, subject to the following restrictions: misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ==================================================================================================== -Total license count: 309 +Total license count: 321 diff --git a/ci/licenses_golden/tool_signature b/ci/licenses_golden/tool_signature index c44f0c985ad7d..580f119ff4ab5 100644 --- a/ci/licenses_golden/tool_signature +++ b/ci/licenses_golden/tool_signature @@ -1,2 +1,2 @@ -Signature: c3d53eebec5b6c8992029095408c2d8c +Signature: ab4f82ed4f38f0d3821073855c220992 diff --git a/common/config.gni b/common/config.gni index f81be4aac0e7a..8d92c84037545 100644 --- a/common/config.gni +++ b/common/config.gni @@ -6,14 +6,15 @@ if (is_android) { import("//build/config/android/config.gni") } +if (is_fuchsia) { + import("//build/fuchsia/sdk.gni") +} + if (target_cpu == "arm" || target_cpu == "arm64") { import("//build/config/arm.gni") } declare_args() { - # Enable ahead-of-time compilation on platforms where AOT is optional. - flutter_aot = false - # The runtime mode ("debug", "profile", "release", "dynamic_profile", or "dynamic_release") flutter_runtime_mode = "debug" } @@ -42,6 +43,6 @@ if (flutter_runtime_mode == "debug") { feature_defines_list += [ "FLUTTER_RUNTIME_MODE=0" ] } -if (flutter_aot) { - feature_defines_list += [ "FLUTTER_AOT=1" ] +if (is_fuchsia && using_fuchsia_sdk) { + feature_defines_list += [ "FUCHSIA_SDK=1" ] } diff --git a/common/exported_symbols.sym b/common/exported_symbols.sym new file mode 100644 index 0000000000000..d85c253e3c07b --- /dev/null +++ b/common/exported_symbols.sym @@ -0,0 +1,8 @@ +# These symbols are looked up from within the executable at runtime and must +# be exported in the dynamic symbol table. +{ + kDartVmSnapshotData; + kDartVmSnapshotInstructions; + kDartIsolateSnapshotData; + kDartIsolateSnapshotInstructions; +}; diff --git a/common/settings.cc b/common/settings.cc index d03c52157e141..7dae838f4ac7f 100644 --- a/common/settings.cc +++ b/common/settings.cc @@ -6,7 +6,7 @@ #include -namespace blink { +namespace flutter { Settings::Settings() = default; @@ -33,6 +33,9 @@ std::string Settings::ToString() const { stream << "start_paused: " << start_paused << std::endl; stream << "trace_skia: " << trace_skia << std::endl; stream << "trace_startup: " << trace_startup << std::endl; + stream << "trace_systrace: " << trace_systrace << std::endl; + stream << "dump_skp_on_shader_compilation: " << dump_skp_on_shader_compilation + << std::endl; stream << "endless_trace_buffer: " << endless_trace_buffer << std::endl; stream << "enable_dart_profiling: " << enable_dart_profiling << std::endl; stream << "disable_dart_asserts: " << disable_dart_asserts << std::endl; @@ -43,10 +46,12 @@ std::string Settings::ToString() const { stream << "enable_software_rendering: " << enable_software_rendering << std::endl; stream << "log_tag: " << log_tag << std::endl; + stream << "icu_initialization_required: " << icu_initialization_required + << std::endl; stream << "icu_data_path: " << icu_data_path << std::endl; stream << "assets_dir: " << assets_dir << std::endl; stream << "assets_path: " << assets_path << std::endl; return stream.str(); } -} // namespace blink +} // namespace flutter diff --git a/common/settings.h b/common/settings.h index d51052f3c1ee6..58f940535291e 100644 --- a/common/settings.h +++ b/common/settings.h @@ -16,7 +16,7 @@ #include "flutter/fml/mapping.h" #include "flutter/fml/unique_fd.h" -namespace blink { +namespace flutter { using TaskObserverAdd = std::function; @@ -29,6 +29,8 @@ using UnhandledExceptionCallback = // callback that generates the mapping from these paths. // https://github.com/flutter/flutter/issues/26783 using MappingCallback = std::function(void)>; +using MappingsCallback = + std::function>(void)>; struct Settings { Settings(); @@ -48,18 +50,27 @@ struct Settings { std::string isolate_snapshot_instr_path; // deprecated MappingCallback isolate_snapshot_instr; + // Returns the Mapping to a kernel buffer which contains sources for dart:* + // libraries. + MappingCallback dart_library_sources_kernel; + std::string application_library_path; - std::string application_kernel_asset; - std::string application_kernel_list_asset; + + std::string application_kernel_asset; // deprecated + std::string application_kernel_list_asset; // deprecated + MappingsCallback application_kernels; std::string temp_directory_path; std::vector dart_flags; + // Arguments passed as a List to Dart's entrypoint function. + std::vector dart_entrypoint_args; // Isolate settings bool start_paused = false; bool trace_skia = false; bool trace_startup = false; bool trace_systrace = false; + bool dump_skp_on_shader_compilation = false; bool endless_trace_buffer = false; bool enable_dart_profiling = false; bool disable_dart_asserts = false; @@ -77,18 +88,38 @@ struct Settings { uint32_t observatory_port = 0; bool ipv6 = false; + // Determines whether an authentication code is required to communicate with + // the VM service. + bool disable_service_auth_codes = true; + // Font settings bool use_test_fonts = false; + // All shells in the process share the same VM. The last shell to shutdown + // should typically shut down the VM as well. However, applications depend on + // the behavior of "warming-up" the VM by creating a shell that does not do + // anything. This used to work earlier when the VM could not be shut down (and + // hence never was). Shutting down the VM now breaks such assumptions in + // existing embedders. To keep this behavior consistent and allow existing + // embedders the chance to migrate, this flag defaults to true. Any shell + // launched with this flag set to true will leak the VM in the process. There + // is no way to shut down the VM once such a shell has been started. All + // shells in the platform (via their embedding APIs) should cooperate to make + // sure this flag is never set if they want the VM to shutdown and free all + // associated resources. + bool leak_vm = true; + // Engine settings TaskObserverAdd task_observer_add; TaskObserverRemove task_observer_remove; // The main isolate is current when this callback is made. This is a good spot // to perform native Dart bindings for libraries not built in. fml::closure root_isolate_create_callback; + fml::closure isolate_create_callback; // The isolate is not current and may have already been destroyed when this // call is made. fml::closure root_isolate_shutdown_callback; + fml::closure isolate_shutdown_callback; // The callback made on the UI thread in an isolate scope when the engine // detects that the framework is idle. The VM also uses this time to perform // tasks suitable when idling. Due to this, embedders are still advised to be @@ -97,13 +128,19 @@ struct Settings { std::function idle_notification_callback; // A callback given to the embedder to react to unhandled exceptions in the // running Flutter application. This callback is made on an internal engine - // managed thread and embedders must thread as necessary. Performing blocking - // calls in this callback will cause applications to jank. + // managed thread and embedders must re-thread as necessary. Performing + // blocking calls in this callback will cause applications to jank. UnhandledExceptionCallback unhandled_exception_callback; bool enable_software_rendering = false; bool skia_deterministic_rendering_on_cpu = false; bool verbose_logging = false; std::string log_tag = "flutter"; + + // The icu_initialization_required setting does not have a corresponding + // switch because it is intended to be decided during build time, not runtime. + // Some companies apply source modification here because their build system + // brings its own ICU data files. + bool icu_initialization_required = true; std::string icu_data_path; MappingCallback icu_mapper; @@ -111,11 +148,10 @@ struct Settings { fml::UniqueFD::element_type assets_dir = fml::UniqueFD::traits_type::InvalidValue(); std::string assets_path; - std::string flx_path; std::string ToString() const; }; -} // namespace blink +} // namespace flutter #endif // FLUTTER_COMMON_SETTINGS_H_ diff --git a/common/task_runners.cc b/common/task_runners.cc index d76bc20f6ae38..baa0d2b132c91 100644 --- a/common/task_runners.cc +++ b/common/task_runners.cc @@ -6,7 +6,7 @@ #include -namespace blink { +namespace flutter { TaskRunners::TaskRunners(std::string label, fml::RefPtr platform, @@ -47,4 +47,4 @@ bool TaskRunners::IsValid() const { return platform_ && gpu_ && ui_ && io_; } -} // namespace blink +} // namespace flutter diff --git a/common/task_runners.h b/common/task_runners.h index 0bd0c301903ae..6e08abcad1d1d 100644 --- a/common/task_runners.h +++ b/common/task_runners.h @@ -10,7 +10,7 @@ #include "flutter/fml/macros.h" #include "flutter/fml/task_runner.h" -namespace blink { +namespace flutter { class TaskRunners { public: @@ -44,6 +44,6 @@ class TaskRunners { fml::RefPtr io_; }; -} // namespace blink +} // namespace flutter #endif // FLUTTER_COMMON_TASK_RUNNERS_H_ diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 799c23caf02d3..603682f3cc278 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -2,6 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +if (is_fuchsia) { + import("//build/fuchsia/sdk.gni") +} + source_set("flow") { sources = [ "compositor_context.cc", @@ -65,7 +69,6 @@ source_set("flow") { deps = [ "$flutter_root/common", "$flutter_root/fml", - "$flutter_root/synchronization", "//third_party/skia", ] @@ -77,15 +80,23 @@ source_set("flow") { "layers/child_scene_layer.h", "scene_update_context.cc", "scene_update_context.h", + "view_holder.cc", + "view_holder.h", ] - public_deps += [ - "//garnet/public/fidl/fuchsia.ui.scenic", - "//garnet/public/lib/ui/scenic/cpp", - "//topaz/public/dart-pkg/zircon", - ] - - public_deps += [ "//zircon/public/lib/zx" ] + if (using_fuchsia_sdk) { + public_deps += [ + "$fuchsia_sdk_root/fidl:fuchsia.ui.gfx", + "$fuchsia_sdk_root/pkg:scenic_cpp", + ] + } else { + public_deps += [ + "//garnet/public/lib/ui/scenic/cpp", + "//sdk/fidl/fuchsia.ui.scenic", + "//topaz/public/dart-pkg/zircon", + "//zircon/public/lib/zx", + ] + } } } @@ -93,14 +104,19 @@ executable("flow_unittests") { testonly = true sources = [ + "flow_run_all_unittests.cc", + "flow_test_utils.cc", + "flow_test_utils.h", + "layers/performance_overlay_layer_unittests.cc", "matrix_decomposition_unittests.cc", "raster_cache_unittests.cc", ] deps = [ ":flow", - "$flutter_root/testing", + "$flutter_root/fml", "//third_party/dart/runtime:libdart_jit", # for tracing + "//third_party/googletest:gtest", "//third_party/skia", ] } diff --git a/flow/compositor_context.cc b/flow/compositor_context.cc index 8dc6883597999..bf38894b10813 100644 --- a/flow/compositor_context.cc +++ b/flow/compositor_context.cc @@ -7,7 +7,7 @@ #include "flutter/flow/layers/layer_tree.h" #include "third_party/skia/include/core/SkCanvas.h" -namespace flow { +namespace flutter { CompositorContext::CompositorContext() = default; @@ -17,7 +17,7 @@ void CompositorContext::BeginFrame(ScopedFrame& frame, bool enable_instrumentation) { if (enable_instrumentation) { frame_count_.Increment(); - frame_time_.Start(); + raster_time_.Start(); } } @@ -25,7 +25,7 @@ void CompositorContext::EndFrame(ScopedFrame& frame, bool enable_instrumentation) { raster_cache_.SweepAfterFrame(); if (enable_instrumentation) { - frame_time_.Stop(); + raster_time_.Stop(); } } @@ -60,9 +60,14 @@ CompositorContext::ScopedFrame::~ScopedFrame() { context_.EndFrame(*this, instrumentation_enabled_); } -bool CompositorContext::ScopedFrame::Raster(flow::LayerTree& layer_tree, +bool CompositorContext::ScopedFrame::Raster(flutter::LayerTree& layer_tree, bool ignore_raster_cache) { layer_tree.Preroll(*this, ignore_raster_cache); + // Clearing canvas after preroll reduces one render target switch when preroll + // paints some raster cache. + if (canvas()) { + canvas()->clear(SK_ColorTRANSPARENT); + } layer_tree.Paint(*this, ignore_raster_cache); return true; } @@ -77,4 +82,4 @@ void CompositorContext::OnGrContextDestroyed() { raster_cache_.Clear(); } -} // namespace flow +} // namespace flutter diff --git a/flow/compositor_context.h b/flow/compositor_context.h index f3a885ccedd3c..4266c943d107e 100644 --- a/flow/compositor_context.h +++ b/flow/compositor_context.h @@ -16,7 +16,7 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" -namespace flow { +namespace flutter { class LayerTree; @@ -79,16 +79,16 @@ class CompositorContext { const Counter& frame_count() const { return frame_count_; } - const Stopwatch& frame_time() const { return frame_time_; } + const Stopwatch& raster_time() const { return raster_time_; } - Stopwatch& engine_time() { return engine_time_; } + Stopwatch& ui_time() { return ui_time_; } private: RasterCache raster_cache_; TextureRegistry texture_registry_; Counter frame_count_; - Stopwatch frame_time_; - Stopwatch engine_time_; + Stopwatch raster_time_; + Stopwatch ui_time_; void BeginFrame(ScopedFrame& frame, bool enable_instrumentation); @@ -97,6 +97,6 @@ class CompositorContext { FML_DISALLOW_COPY_AND_ASSIGN(CompositorContext); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_COMPOSITOR_CONTEXT_H_ diff --git a/flow/debug_print.cc b/flow/debug_print.cc index a41171313540d..965c3c2c78614 100644 --- a/flow/debug_print.cc +++ b/flow/debug_print.cc @@ -8,7 +8,8 @@ #include "third_party/skia/include/core/SkString.h" -std::ostream& operator<<(std::ostream& os, const flow::MatrixDecomposition& m) { +std::ostream& operator<<(std::ostream& os, + const flutter::MatrixDecomposition& m) { if (!m.IsValid()) { os << "Invalid Matrix!" << std::endl; return os; @@ -72,7 +73,7 @@ std::ostream& operator<<(std::ostream& os, const SkPoint& r) { } std::ostream& operator<<(std::ostream& os, - const flow::PictureRasterCacheKey& k) { + const flutter::PictureRasterCacheKey& k) { os << "Picture: " << k.id() << " matrix: " << k.matrix(); return os; } diff --git a/flow/debug_print.h b/flow/debug_print.h index 34621e314ad2a..f8e0d239c8c86 100644 --- a/flow/debug_print.h +++ b/flow/debug_print.h @@ -15,8 +15,8 @@ #define DEF_PRINTER(x) std::ostream& operator<<(std::ostream&, const x&); -DEF_PRINTER(flow::MatrixDecomposition); -DEF_PRINTER(flow::PictureRasterCacheKey); +DEF_PRINTER(flutter::MatrixDecomposition); +DEF_PRINTER(flutter::PictureRasterCacheKey); DEF_PRINTER(SkISize); DEF_PRINTER(SkMatrix); DEF_PRINTER(SkMatrix44); diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index 8dc634ecdd62d..e37a837deec0e 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -4,9 +4,9 @@ #include "flutter/flow/embedded_views.h" -namespace flow { +namespace flutter { bool ExternalViewEmbedder::SubmitFrame(GrContext* context) { return false; }; -} // namespace flow +} // namespace flutter diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 6f2e684c4841e..e7b34f753bc38 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -12,7 +12,7 @@ #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkSize.h" -namespace flow { +namespace flutter { class EmbeddedViewParams { public: @@ -21,7 +21,7 @@ class EmbeddedViewParams { }; // This is only used on iOS when running in a non headless mode, -// in this case ViewEmbedded is a reference to the +// in this case ExternalViewEmbedder is a reference to the // FlutterPlatformViewsController which is owned by FlutterViewController. class ExternalViewEmbedder { public: @@ -44,6 +44,6 @@ class ExternalViewEmbedder { FML_DISALLOW_COPY_AND_ASSIGN(ExternalViewEmbedder); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_EMBEDDED_VIEWS_H_ diff --git a/flow/export_node.cc b/flow/export_node.cc index acf7e42da3215..318b52ff3cc27 100644 --- a/flow/export_node.cc +++ b/flow/export_node.cc @@ -4,81 +4,77 @@ #include "flutter/flow/export_node.h" -#include "flutter/fml/make_copyable.h" +#include "flutter/fml/thread_local.h" -namespace flow { +namespace { -ExportNodeHolder::ExportNodeHolder( - fml::RefPtr gpu_task_runner, - fml::RefPtr export_token_handle) - : gpu_task_runner_(std::move(gpu_task_runner)), - export_node_(std::make_unique(export_token_handle)) { - FML_DCHECK(gpu_task_runner_); -} +using ExportNodeBindings = + std::unordered_map>; + +FML_THREAD_LOCAL fml::ThreadLocalUniquePtr + tls_export_node_bindings; + +} // namespace + +namespace flutter { -void ExportNodeHolder::Bind(SceneUpdateContext& context, - scenic::ContainerNode& container, - const SkPoint& offset, - bool hit_testable) { - export_node_->Bind(context, container, offset, hit_testable); +ExportNode::ExportNode(zx::eventpair export_token) + : pending_export_token_(std::move(export_token)) { + FML_DCHECK(pending_export_token_); } -ExportNodeHolder::~ExportNodeHolder() { - gpu_task_runner_->PostTask( - fml::MakeCopyable([export_node = std::move(export_node_)]() { - export_node->Dispose(true); - })); +void ExportNode::Create(zx_koid_t id, zx::eventpair export_token) { + // This GPU thread contains at least 1 ViewHolder. Initialize the per-thread + // bindings. + if (tls_export_node_bindings.get() == nullptr) { + tls_export_node_bindings.reset(new ExportNodeBindings()); + } + + auto* bindings = tls_export_node_bindings.get(); + FML_DCHECK(bindings); + FML_DCHECK(bindings->find(id) == bindings->end()); + + auto export_node = + std::unique_ptr(new ExportNode(std::move(export_token))); + bindings->emplace(id, std::move(export_node)); } -ExportNode::ExportNode(fml::RefPtr export_token_handle) - : export_token_(export_token_handle->ReleaseHandle()) {} +void ExportNode::Destroy(zx_koid_t id) { + auto* bindings = tls_export_node_bindings.get(); + FML_DCHECK(bindings); -ExportNode::~ExportNode() { - // Ensure that we properly released the node. - FML_DCHECK(!node_); - FML_DCHECK(scene_update_context_ == nullptr); + bindings->erase(id); } -void ExportNode::Bind(SceneUpdateContext& context, - scenic::ContainerNode& container, - const SkPoint& offset, - bool hit_testable) { - if (export_token_) { - // Happens first time we bind. - node_.reset(new scenic::EntityNode(container.session())); - node_->Export(std::move(export_token_)); - - // Add ourselves to the context so it can call Dispose() on us if the Scenic - // session is closed. - context.AddExportNode(this); - scene_update_context_ = &context; +ExportNode* ExportNode::FromId(zx_koid_t id) { + auto* bindings = tls_export_node_bindings.get(); + if (!bindings) { + return nullptr; } - if (node_) { - container.AddChild(*node_); - node_->SetTranslation(offset.x(), offset.y(), 0.f); - node_->SetHitTestBehavior( - hit_testable ? fuchsia::ui::gfx::HitTestBehavior::kDefault - : fuchsia::ui::gfx::HitTestBehavior::kSuppress); + auto binding = bindings->find(id); + if (binding == bindings->end()) { + return nullptr; } + + return binding->second.get(); } -void ExportNode::Dispose(bool remove_from_scene_update_context) { - // If scene_update_context_ is set, then we should still have a node left to - // dereference. - // If scene_update_context_ is null, then either: - // 1. A node was never created, or - // 2. A node was created but was already dereferenced (i.e. Dispose has - // already been called). - FML_DCHECK(scene_update_context_ || !node_); - - if (remove_from_scene_update_context && scene_update_context_) { - scene_update_context_->RemoveExportNode(this); +void ExportNode::UpdateScene(SceneUpdateContext& context, + const SkPoint& offset, + const SkSize& size, + bool hit_testable) { + if (pending_export_token_) { + export_node_ = std::make_unique(context.session()); + export_node_->Export(std::move(pending_export_token_)); } + FML_DCHECK(export_node_); - scene_update_context_ = nullptr; - export_token_.reset(); - node_ = nullptr; + context.top_entity()->entity_node().AddChild(*export_node_); + export_node_->SetTranslation(offset.x(), offset.y(), -0.1f); + export_node_->SetHitTestBehavior( + hit_testable ? fuchsia::ui::gfx::HitTestBehavior::kDefault + : fuchsia::ui::gfx::HitTestBehavior::kSuppress); } -} // namespace flow +} // namespace flutter diff --git a/flow/export_node.h b/flow/export_node.h index 20be1e45f7bfa..dfc72052d65fd 100644 --- a/flow/export_node.h +++ b/flow/export_node.h @@ -5,79 +5,46 @@ #ifndef FLUTTER_FLOW_EXPORT_NODE_H_ #define FLUTTER_FLOW_EXPORT_NODE_H_ -#include +#include +#include +#include +#include +#include +#include -#include +#include -#include "dart-pkg/zircon/sdk_ext/handle.h" #include "flutter/flow/scene_update_context.h" -#include "flutter/fml/build_config.h" #include "flutter/fml/macros.h" -#include "flutter/fml/memory/ref_counted.h" -#include "lib/ui/scenic/cpp/resources.h" -#include "third_party/flutter/fml/task_runner.h" -#include "third_party/skia/include/core/SkPoint.h" - -namespace flow { - -// Wrapper class for ExportNode to use on UI Thread. When ExportNodeHolder is -// destroyed, a task is posted on the Rasterizer thread to dispose the resources -// held by the ExportNode. -class ExportNodeHolder : public fml::RefCountedThreadSafe { - public: - ExportNodeHolder(fml::RefPtr gpu_task_runner, - fml::RefPtr export_token_handle); - ~ExportNodeHolder(); - - // Calls Bind() on the wrapped ExportNode. - void Bind(SceneUpdateContext& context, - scenic::ContainerNode& container, - const SkPoint& offset, - bool hit_testable); - ExportNode* export_node() { return export_node_.get(); } +namespace flutter { - private: - fml::RefPtr gpu_task_runner_; - std::unique_ptr export_node_; - - FML_FRIEND_MAKE_REF_COUNTED(ExportNodeHolder); - FML_FRIEND_REF_COUNTED_THREAD_SAFE(ExportNodeHolder); - FML_DISALLOW_COPY_AND_ASSIGN(ExportNodeHolder); -}; - -// Represents a node which is being exported from the session. -// This object is created on the UI thread but the entity node it contains -// must be created and destroyed by the rasterizer thread. +// Represents a Scenic |ExportNode| resource that exports an |EntityNode| to +// another session. +// +// This object is created and destroyed on the |Rasterizer|'s' thread. class ExportNode { public: - ExportNode(fml::RefPtr export_token_handle); - - ~ExportNode(); + static void Create(zx_koid_t id, zx::eventpair export_token); + static void Destroy(zx_koid_t id); + static ExportNode* FromId(zx_koid_t id); - // Binds the export token to the entity node and adds it as a child of - // the specified container. Must be called on the Rasterizer thread. - void Bind(SceneUpdateContext& context, - scenic::ContainerNode& container, - const SkPoint& offset, - bool hit_testable); + // Creates or updates the contained EntityNode resource using the specified + // |SceneUpdateContext|. + void UpdateScene(SceneUpdateContext& context, + const SkPoint& offset, + const SkSize& size, + bool hit_testable); private: - friend class SceneUpdateContext; - friend class ExportNodeHolder; - - // Cleans up resources held and removes this ExportNode from - // SceneUpdateContext. Must be called on the Rasterizer thread. - void Dispose(bool remove_from_scene_update_context); + ExportNode(zx::eventpair export_token); - // Member variables can only be read or modified on Rasterizer thread. - SceneUpdateContext* scene_update_context_ = nullptr; - zx::eventpair export_token_; - std::unique_ptr node_; + zx::eventpair pending_export_token_; + std::unique_ptr export_node_; FML_DISALLOW_COPY_AND_ASSIGN(ExportNode); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_EXPORT_NODE_H_ diff --git a/flow/flow_run_all_unittests.cc b/flow/flow_run_all_unittests.cc new file mode 100644 index 0000000000000..4cf0ba3d7fcdf --- /dev/null +++ b/flow/flow_run_all_unittests.cc @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "flutter/fml/command_line.h" +#include "flutter/fml/logging.h" +#include "gtest/gtest.h" + +#include "flow_test_utils.h" + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + fml::CommandLine cmd = fml::CommandLineFromArgcArgv(argc, argv); + flutter::SetGoldenDir( + cmd.GetOptionValueWithDefault("golden-dir", "flutter/testing/resources")); + flutter::SetFontFile(cmd.GetOptionValueWithDefault( + "font-file", + "flutter/third_party/txt/third_party/fonts/Roboto-Regular.ttf")); + return RUN_ALL_TESTS(); +} diff --git a/flow/flow_test_utils.cc b/flow/flow_test_utils.cc new file mode 100644 index 0000000000000..bde6d9b46776a --- /dev/null +++ b/flow/flow_test_utils.cc @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace flutter { + +static std::string gGoldenDir; +static std::string gFontFile; + +const std::string& GetGoldenDir() { + return gGoldenDir; +} + +void SetGoldenDir(const std::string& dir) { + gGoldenDir = dir; +} + +const std::string& GetFontFile() { + return gFontFile; +} + +void SetFontFile(const std::string& file) { + gFontFile = file; +} + +} // namespace flutter diff --git a/flow/flow_test_utils.h b/flow/flow_test_utils.h new file mode 100644 index 0000000000000..1e5e5cddb842a --- /dev/null +++ b/flow/flow_test_utils.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace flutter { + +const std::string& GetGoldenDir(); + +void SetGoldenDir(const std::string& dir); + +const std::string& GetFontFile(); + +void SetFontFile(const std::string& dir); + +} // namespace flutter diff --git a/flow/instrumentation.cc b/flow/instrumentation.cc index ae9846c557f4c..19270dc6a40f9 100644 --- a/flow/instrumentation.cc +++ b/flow/instrumentation.cc @@ -10,7 +10,7 @@ #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkSurface.h" -namespace flow { +namespace flutter { static const size_t kMaxSamples = 120; static const size_t kMaxFrameMarkers = 8; @@ -42,13 +42,13 @@ const fml::TimeDelta& Stopwatch::LastLap() const { return laps_[(current_sample_ - 1) % kMaxSamples]; } -static inline constexpr double UnitFrameInterval(double frame_time_ms) { - return frame_time_ms * 60.0 * 1e-3; +static inline constexpr double UnitFrameInterval(double raster_time_ms) { + return raster_time_ms * 60.0 * 1e-3; } -static inline double UnitHeight(double frame_time_ms, +static inline double UnitHeight(double raster_time_ms, double max_unit_interval) { - double unitHeight = UnitFrameInterval(frame_time_ms) / max_unit_interval; + double unitHeight = UnitFrameInterval(raster_time_ms) / max_unit_interval; if (unitHeight > 1.0) unitHeight = 1.0; return unitHeight; @@ -311,4 +311,4 @@ int64_t CounterValues::GetMinValue() const { return min; } -} // namespace flow +} // namespace flutter diff --git a/flow/instrumentation.h b/flow/instrumentation.h index a991af5b583da..aae76cc81989c 100644 --- a/flow/instrumentation.h +++ b/flow/instrumentation.h @@ -12,7 +12,7 @@ #include "flutter/fml/time/time_point.h" #include "third_party/skia/include/core/SkCanvas.h" -namespace flow { +namespace flutter { // DEPRECATED // The frame per second FPS could be different than 60 (e.g., 120). @@ -94,6 +94,6 @@ class CounterValues { FML_DISALLOW_COPY_AND_ASSIGN(CounterValues); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_INSTRUMENTATION_H_ diff --git a/flow/layers/backdrop_filter_layer.cc b/flow/layers/backdrop_filter_layer.cc index f45c28b7d2381..cfa678e39ef53 100644 --- a/flow/layers/backdrop_filter_layer.cc +++ b/flow/layers/backdrop_filter_layer.cc @@ -4,7 +4,7 @@ #include "flutter/flow/layers/backdrop_filter_layer.h" -namespace flow { +namespace flutter { BackdropFilterLayer::BackdropFilterLayer() = default; @@ -20,4 +20,4 @@ void BackdropFilterLayer::Paint(PaintContext& context) const { PaintChildren(context); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/backdrop_filter_layer.h b/flow/layers/backdrop_filter_layer.h index 39bd64c33b23e..b273427371634 100644 --- a/flow/layers/backdrop_filter_layer.h +++ b/flow/layers/backdrop_filter_layer.h @@ -9,7 +9,7 @@ #include "third_party/skia/include/core/SkImageFilter.h" -namespace flow { +namespace flutter { class BackdropFilterLayer : public ContainerLayer { public: @@ -26,6 +26,6 @@ class BackdropFilterLayer : public ContainerLayer { FML_DISALLOW_COPY_AND_ASSIGN(BackdropFilterLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_BACKDROP_FILTER_LAYER_H_ diff --git a/flow/layers/child_scene_layer.cc b/flow/layers/child_scene_layer.cc index 162a8d1a4df50..37937f1af71b3 100644 --- a/flow/layers/child_scene_layer.cc +++ b/flow/layers/child_scene_layer.cc @@ -4,32 +4,44 @@ #include "flutter/flow/layers/child_scene_layer.h" -namespace flow { - -ChildSceneLayer::ChildSceneLayer() = default; - -ChildSceneLayer::~ChildSceneLayer() = default; +#include "flutter/flow/export_node.h" +#include "flutter/flow/view_holder.h" + +namespace flutter { + +ChildSceneLayer::ChildSceneLayer(zx_koid_t layer_id, + bool use_view_holder, + const SkPoint& offset, + const SkSize& size, + bool hit_testable) + : layer_id_(layer_id), + offset_(offset), + size_(size), + hit_testable_(hit_testable), + use_view_holder_(use_view_holder) {} void ChildSceneLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { set_needs_system_composite(true); } void ChildSceneLayer::Paint(PaintContext& context) const { - FXL_NOTREACHED() << "This layer never needs painting."; + FML_NOTREACHED() << "This layer never needs painting."; } void ChildSceneLayer::UpdateScene(SceneUpdateContext& context) { FML_DCHECK(needs_system_composite()); - // TODO(MZ-191): Set clip. - // It's worth asking whether all children should be clipped implicitly - // or whether we should leave this up to the Flutter application to decide. - // In some situations, it might be useful to allow children to draw - // outside of their layout bounds. - if (export_node_holder_) { - context.AddChildScene(export_node_holder_->export_node(), offset_, - hit_testable_); + if (use_view_holder_) { + auto* view_holder = ViewHolder::FromId(layer_id_); + FML_DCHECK(view_holder); + + view_holder->UpdateScene(context, offset_, size_, hit_testable_); + } else { + auto* export_node = ExportNode::FromId(layer_id_); + FML_DCHECK(export_node); + + export_node->UpdateScene(context, offset_, size_, hit_testable_); } } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/child_scene_layer.h b/flow/layers/child_scene_layer.h index 89fd367a0e69b..d3639850da4f6 100644 --- a/flow/layers/child_scene_layer.h +++ b/flow/layers/child_scene_layer.h @@ -5,27 +5,24 @@ #ifndef FLUTTER_FLOW_LAYERS_CHILD_SCENE_LAYER_H_ #define FLUTTER_FLOW_LAYERS_CHILD_SCENE_LAYER_H_ -#include "flutter/flow/export_node.h" +#include +#include +#include + #include "flutter/flow/layers/layer.h" +#include "flutter/flow/scene_update_context.h" -namespace flow { +namespace flutter { // Layer that represents an embedded child. class ChildSceneLayer : public Layer { public: - ChildSceneLayer(); - ~ChildSceneLayer() override; - - void set_offset(const SkPoint& offset) { offset_ = offset; } - - void set_size(const SkSize& size) { size_ = size; } - - void set_export_node_holder( - fml::RefPtr export_node_holder) { - export_node_holder_ = std::move(export_node_holder); - } - - void set_hit_testable(bool hit_testable) { hit_testable_ = hit_testable; } + ChildSceneLayer(zx_koid_t layer_id, + bool use_view_holder, + const SkPoint& offset, + const SkSize& size, + bool hit_testable); + ~ChildSceneLayer() override = default; void Preroll(PrerollContext* context, const SkMatrix& matrix) override; @@ -34,14 +31,15 @@ class ChildSceneLayer : public Layer { void UpdateScene(SceneUpdateContext& context) override; private: + zx_koid_t layer_id_ = ZX_KOID_INVALID; SkPoint offset_; SkSize size_; - fml::RefPtr export_node_holder_; bool hit_testable_ = true; + bool use_view_holder_ = true; FML_DISALLOW_COPY_AND_ASSIGN(ChildSceneLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_CHILD_SCENE_LAYER_H_ diff --git a/flow/layers/clip_path_layer.cc b/flow/layers/clip_path_layer.cc index c6259de22aa53..cdca4619a3707 100644 --- a/flow/layers/clip_path_layer.cc +++ b/flow/layers/clip_path_layer.cc @@ -6,14 +6,16 @@ #if defined(OS_FUCHSIA) -#include "lib/ui/scenic/fidl_helpers.h" // nogncheck +#include "lib/ui/scenic/cpp/commands.h" #endif // defined(OS_FUCHSIA) -namespace flow { +namespace flutter { ClipPathLayer::ClipPathLayer(Clip clip_behavior) - : clip_behavior_(clip_behavior) {} + : clip_behavior_(clip_behavior) { + FML_DCHECK(clip_behavior != Clip::none); +} ClipPathLayer::~ClipPathLayer() = default; @@ -36,7 +38,7 @@ void ClipPathLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { void ClipPathLayer::UpdateScene(SceneUpdateContext& context) { FML_DCHECK(needs_system_composite()); - // TODO(MZ-140): Must be able to specify paths as shapes to nodes. + // TODO(SCN-140): Must be able to specify paths as shapes to nodes. // Treating the shape as a rectangle for now. auto bounds = clip_path_.getBounds(); scenic::Rectangle shape(context.session(), // session @@ -67,4 +69,4 @@ void ClipPathLayer::Paint(PaintContext& context) const { } } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/clip_path_layer.h b/flow/layers/clip_path_layer.h index 7b6de1f60f516..814e6c2bd2002 100644 --- a/flow/layers/clip_path_layer.h +++ b/flow/layers/clip_path_layer.h @@ -7,7 +7,7 @@ #include "flutter/flow/layers/container_layer.h" -namespace flow { +namespace flutter { class ClipPathLayer : public ContainerLayer { public: @@ -31,6 +31,6 @@ class ClipPathLayer : public ContainerLayer { FML_DISALLOW_COPY_AND_ASSIGN(ClipPathLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_CLIP_PATH_LAYER_H_ diff --git a/flow/layers/clip_rect_layer.cc b/flow/layers/clip_rect_layer.cc index 3f39daca244c2..3f41d8768c6b3 100644 --- a/flow/layers/clip_rect_layer.cc +++ b/flow/layers/clip_rect_layer.cc @@ -4,10 +4,12 @@ #include "flutter/flow/layers/clip_rect_layer.h" -namespace flow { +namespace flutter { ClipRectLayer::ClipRectLayer(Clip clip_behavior) - : clip_behavior_(clip_behavior) {} + : clip_behavior_(clip_behavior) { + FML_DCHECK(clip_behavior != Clip::none); +} ClipRectLayer::~ClipRectLayer() = default; @@ -46,10 +48,10 @@ void ClipRectLayer::Paint(PaintContext& context) const { FML_DCHECK(needs_painting()); SkAutoCanvasRestore save(context.internal_nodes_canvas, true); - context.internal_nodes_canvas->clipRect(paint_bounds(), + context.internal_nodes_canvas->clipRect(clip_rect_, clip_behavior_ != Clip::hardEdge); if (clip_behavior_ == Clip::antiAliasWithSaveLayer) { - context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr); + context.internal_nodes_canvas->saveLayer(clip_rect_, nullptr); } PaintChildren(context); if (clip_behavior_ == Clip::antiAliasWithSaveLayer) { @@ -57,4 +59,4 @@ void ClipRectLayer::Paint(PaintContext& context) const { } } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/clip_rect_layer.h b/flow/layers/clip_rect_layer.h index 76e10e49bb7ea..56f3d1a826cfe 100644 --- a/flow/layers/clip_rect_layer.h +++ b/flow/layers/clip_rect_layer.h @@ -7,7 +7,7 @@ #include "flutter/flow/layers/container_layer.h" -namespace flow { +namespace flutter { class ClipRectLayer : public ContainerLayer { public: @@ -30,6 +30,6 @@ class ClipRectLayer : public ContainerLayer { FML_DISALLOW_COPY_AND_ASSIGN(ClipRectLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_CLIP_RECT_LAYER_H_ diff --git a/flow/layers/clip_rrect_layer.cc b/flow/layers/clip_rrect_layer.cc index 896ec1ae27f10..d387f58b1dc72 100644 --- a/flow/layers/clip_rrect_layer.cc +++ b/flow/layers/clip_rrect_layer.cc @@ -4,10 +4,12 @@ #include "flutter/flow/layers/clip_rrect_layer.h" -namespace flow { +namespace flutter { ClipRRectLayer::ClipRRectLayer(Clip clip_behavior) - : clip_behavior_(clip_behavior) {} + : clip_behavior_(clip_behavior) { + FML_DCHECK(clip_behavior != Clip::none); +} ClipRRectLayer::~ClipRRectLayer() = default; @@ -30,7 +32,7 @@ void ClipRRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { void ClipRRectLayer::UpdateScene(SceneUpdateContext& context) { FML_DCHECK(needs_system_composite()); - // TODO(MZ-137): Need to be able to express the radii as vectors. + // TODO(SCN-137): Need to be able to express the radii as vectors. scenic::RoundedRectangle shape( context.session(), // session clip_rrect_.width(), // width @@ -65,4 +67,4 @@ void ClipRRectLayer::Paint(PaintContext& context) const { } } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/clip_rrect_layer.h b/flow/layers/clip_rrect_layer.h index 7b3ac85beb65b..66bae7cf374b7 100644 --- a/flow/layers/clip_rrect_layer.h +++ b/flow/layers/clip_rrect_layer.h @@ -7,7 +7,7 @@ #include "flutter/flow/layers/container_layer.h" -namespace flow { +namespace flutter { class ClipRRectLayer : public ContainerLayer { public: @@ -31,6 +31,6 @@ class ClipRRectLayer : public ContainerLayer { FML_DISALLOW_COPY_AND_ASSIGN(ClipRRectLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_CLIP_RRECT_LAYER_H_ diff --git a/flow/layers/color_filter_layer.cc b/flow/layers/color_filter_layer.cc index 3b140ad7ceb5e..c52bcdc28f407 100644 --- a/flow/layers/color_filter_layer.cc +++ b/flow/layers/color_filter_layer.cc @@ -4,7 +4,7 @@ #include "flutter/flow/layers/color_filter_layer.h" -namespace flow { +namespace flutter { ColorFilterLayer::ColorFilterLayer() = default; @@ -14,14 +14,12 @@ void ColorFilterLayer::Paint(PaintContext& context) const { TRACE_EVENT0("flutter", "ColorFilterLayer::Paint"); FML_DCHECK(needs_painting()); - sk_sp color_filter = - SkColorFilter::MakeModeFilter(color_, blend_mode_); SkPaint paint; - paint.setColorFilter(std::move(color_filter)); + paint.setColorFilter(SkColorFilters::Blend(color_, blend_mode_)); Layer::AutoSaveLayer save = Layer::AutoSaveLayer::Create(context, paint_bounds(), &paint); PaintChildren(context); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/color_filter_layer.h b/flow/layers/color_filter_layer.h index 358788fdd4486..eec7dae0257c6 100644 --- a/flow/layers/color_filter_layer.h +++ b/flow/layers/color_filter_layer.h @@ -7,7 +7,7 @@ #include "flutter/flow/layers/container_layer.h" -namespace flow { +namespace flutter { class ColorFilterLayer : public ContainerLayer { public: @@ -27,6 +27,6 @@ class ColorFilterLayer : public ContainerLayer { FML_DISALLOW_COPY_AND_ASSIGN(ColorFilterLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_COLOR_FILTER_LAYER_H_ diff --git a/flow/layers/container_layer.cc b/flow/layers/container_layer.cc index f6ca64005fe6b..31a5a255afca9 100644 --- a/flow/layers/container_layer.cc +++ b/flow/layers/container_layer.cc @@ -4,7 +4,7 @@ #include "flutter/flow/layers/container_layer.h" -namespace flow { +namespace flutter { ContainerLayer::ContainerLayer() {} @@ -27,8 +27,7 @@ void ContainerLayer::PrerollChildren(PrerollContext* context, const SkMatrix& child_matrix, SkRect* child_paint_bounds) { for (auto& layer : layers_) { - PrerollContext child_context = *context; - layer->Preroll(&child_context, child_matrix); + layer->Preroll(context, child_matrix); if (layer->needs_system_composite()) { set_needs_system_composite(true); @@ -69,4 +68,4 @@ void ContainerLayer::UpdateSceneChildren(SceneUpdateContext& context) { #endif // defined(OS_FUCHSIA) -} // namespace flow +} // namespace flutter diff --git a/flow/layers/container_layer.h b/flow/layers/container_layer.h index 780fd64b46a94..ef1c03328d1df 100644 --- a/flow/layers/container_layer.h +++ b/flow/layers/container_layer.h @@ -8,7 +8,7 @@ #include #include "flutter/flow/layers/layer.h" -namespace flow { +namespace flutter { class ContainerLayer : public Layer { public: @@ -35,12 +35,15 @@ class ContainerLayer : public Layer { void UpdateSceneChildren(SceneUpdateContext& context); #endif // defined(OS_FUCHSIA) + // For OpacityLayer to restructure to have a single child. + void ClearChildren() { layers_.clear(); } + private: std::vector> layers_; FML_DISALLOW_COPY_AND_ASSIGN(ContainerLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_ diff --git a/flow/layers/layer.cc b/flow/layers/layer.cc index c3653ed52d0cf..b729f582a0a9a 100644 --- a/flow/layers/layer.cc +++ b/flow/layers/layer.cc @@ -7,15 +7,25 @@ #include "flutter/flow/paint_utils.h" #include "third_party/skia/include/core/SkColorFilter.h" -namespace flow { +namespace flutter { Layer::Layer() : parent_(nullptr), needs_system_composite_(false), - paint_bounds_(SkRect::MakeEmpty()) {} + paint_bounds_(SkRect::MakeEmpty()), + unique_id_(NextUniqueID()) {} Layer::~Layer() = default; +uint64_t Layer::NextUniqueID() { + static std::atomic nextID(1); + uint64_t id; + do { + id = nextID.fetch_add(1); + } while (id == 0); // 0 is reserved for an invalid id. + return id; +} + void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {} #if defined(OS_FUCHSIA) @@ -55,4 +65,4 @@ Layer::AutoSaveLayer::~AutoSaveLayer() { paint_context_.internal_nodes_canvas->restore(); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/layer.h b/flow/layers/layer.h index e846d353e52e9..7400af5468214 100644 --- a/flow/layers/layer.h +++ b/flow/layers/layer.h @@ -35,7 +35,7 @@ #endif // defined(OS_FUCHSIA) -namespace flow { +namespace flutter { static constexpr SkRect kGiantRect = SkRect::MakeLTRB(-1E9F, -1E9F, 1E9F, 1E9F); @@ -52,10 +52,11 @@ struct PrerollContext { SkRect cull_rect; // The following allows us to paint in the end of subtree preroll - const Stopwatch& frame_time; - const Stopwatch& engine_time; + const Stopwatch& raster_time; + const Stopwatch& ui_time; TextureRegistry& texture_registry; const bool checkerboard_offscreen_layers; + float total_elevation = 0.0f; }; // Represents a single composited layer. Created on the UI thread but then @@ -80,9 +81,10 @@ class Layer { // layers. SkCanvas* internal_nodes_canvas; SkCanvas* leaf_nodes_canvas; + GrContext* gr_context; ExternalViewEmbedder* view_embedder; - const Stopwatch& frame_time; - const Stopwatch& engine_time; + const Stopwatch& raster_time; + const Stopwatch& ui_time; TextureRegistry& texture_registry; const RasterCache* raster_cache; const bool checkerboard_offscreen_layers; @@ -141,14 +143,19 @@ class Layer { bool needs_painting() const { return !paint_bounds_.isEmpty(); } + uint64_t unique_id() const { return unique_id_; } + private: ContainerLayer* parent_; bool needs_system_composite_; SkRect paint_bounds_; + uint64_t unique_id_; + + static uint64_t NextUniqueID(); FML_DISALLOW_COPY_AND_ASSIGN(Layer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_LAYER_H_ diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index fbe3c2178e75f..70c21604dedb3 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -9,7 +9,7 @@ #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/utils/SkNWayCanvas.h" -namespace flow { +namespace flutter { LayerTree::LayerTree() : frame_size_{}, @@ -32,8 +32,8 @@ void LayerTree::Preroll(CompositorContext::ScopedFrame& frame, frame.view_embedder(), color_space, kGiantRect, - frame.context().frame_time(), - frame.context().engine_time(), + frame.context().raster_time(), + frame.context().ui_time(), frame.context().texture_registry(), checkerboard_offscreen_layers_}; @@ -54,7 +54,7 @@ void LayerTree::UpdateScene(SceneUpdateContext& context, context, SkRRect::MakeRect( SkRect::MakeWH(frame_size_.width(), frame_size_.height())), - SK_ColorTRANSPARENT, 0.f); + SK_ColorTRANSPARENT); if (root_layer_->needs_system_composite()) { root_layer_->UpdateScene(context); } @@ -81,9 +81,10 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, Layer::PaintContext context = { (SkCanvas*)&internal_nodes_canvas, frame.canvas(), + frame.gr_context(), frame.view_embedder(), - frame.context().frame_time(), - frame.context().engine_time(), + frame.context().raster_time(), + frame.context().ui_time(), frame.context().texture_registry(), ignore_raster_cache ? nullptr : &frame.context().raster_cache(), checkerboard_offscreen_layers_}; @@ -128,6 +129,7 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { (SkCanvas*)&internal_nodes_canvas, canvas, // canvas nullptr, + nullptr, unused_stopwatch, // frame time (dont care) unused_stopwatch, // engine time (dont care) unused_texture_registry, // texture registry (not supported) @@ -148,4 +150,4 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { return recorder.finishRecordingAsPicture(); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index f3bfe3a322594..641948bcf77ff 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -16,7 +16,7 @@ #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkSize.h" -namespace flow { +namespace flutter { class LayerTree { public: @@ -83,6 +83,6 @@ class LayerTree { FML_DISALLOW_COPY_AND_ASSIGN(LayerTree); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_LAYER_TREE_H_ diff --git a/flow/layers/opacity_layer.cc b/flow/layers/opacity_layer.cc index c774ab9fb3d94..2af6cb29be3f1 100644 --- a/flow/layers/opacity_layer.cc +++ b/flow/layers/opacity_layer.cc @@ -4,18 +4,45 @@ #include "flutter/flow/layers/opacity_layer.h" -namespace flow { +#include "flutter/flow/layers/transform_layer.h" + +namespace flutter { OpacityLayer::OpacityLayer() = default; OpacityLayer::~OpacityLayer() = default; +void OpacityLayer::EnsureSingleChild() { + FML_DCHECK(layers().size() > 0); // OpacityLayer should never be a leaf + + if (layers().size() == 1) { + return; + } + + auto new_child = std::make_shared(); + + // Be careful: SkMatrix's default constructor doesn't initialize the matrix to + // identity. Hence we have to explicitly call SkMatrix::setIdentity. + SkMatrix identity; + identity.setIdentity(); + + new_child->set_transform(identity); + for (auto& child : layers()) { + new_child->Add(child); + } + ClearChildren(); + Add(new_child); +} + void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { + EnsureSingleChild(); SkMatrix child_matrix = matrix; child_matrix.postTranslate(offset_.fX, offset_.fY); ContainerLayer::Preroll(context, child_matrix); set_paint_bounds(paint_bounds().makeOffset(offset_.fX, offset_.fY)); - if (context->raster_cache && layers().size() == 1 && + // See |EnsureSingleChild|. + FML_DCHECK(layers().size() == 1); + if (context->raster_cache && SkRect::Intersects(context->cull_rect, paint_bounds())) { Layer* child = layers()[0].get(); SkMatrix ctm = child_matrix; @@ -41,12 +68,14 @@ void OpacityLayer::Paint(PaintContext& context) const { context.leaf_nodes_canvas->getTotalMatrix())); #endif + // See |EnsureSingleChild|. + FML_DCHECK(layers().size() == 1); + // Embedded platform views are changing the canvas in the middle of the paint // traversal. To make sure we paint on the right canvas, when the embedded // platform views preview is enabled (context.view_embedded is not null) we // don't use the cache. - if (context.view_embedder == nullptr && layers().size() == 1 && - context.raster_cache) { + if (context.view_embedder == nullptr && context.raster_cache) { const SkMatrix& ctm = context.leaf_nodes_canvas->getTotalMatrix(); RasterCacheResult child_cache = context.raster_cache->Get(layers()[0].get(), ctm); @@ -75,4 +104,4 @@ void OpacityLayer::Paint(PaintContext& context) const { PaintChildren(context); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/opacity_layer.h b/flow/layers/opacity_layer.h index 5662f85a64980..b92f53d65d704 100644 --- a/flow/layers/opacity_layer.h +++ b/flow/layers/opacity_layer.h @@ -7,8 +7,12 @@ #include "flutter/flow/layers/container_layer.h" -namespace flow { +namespace flutter { +// Don't add an OpacityLayer with no children to the layer tree. Painting an +// OpacityLayer is very costly due to the saveLayer call. If there's no child, +// having the OpacityLayer or not has the same effect. In debug_unopt build, the +// |EnsureSingleChild| will assert if there are no children. class OpacityLayer : public ContainerLayer { public: OpacityLayer(); @@ -21,16 +25,26 @@ class OpacityLayer : public ContainerLayer { void Paint(PaintContext& context) const override; - // TODO(chinmaygarde): Once MZ-139 is addressed, introduce a new node in the + // TODO(chinmaygarde): Once SCN-139 is addressed, introduce a new node in the // session scene hierarchy. private: int alpha_; SkPoint offset_; + // Restructure (if necessary) OpacityLayer to have only one child. + // + // This is needed to ensure that retained rendering can always be applied to + // save the costly saveLayer. + // + // If there are multiple children, this creates a new identity TransformLayer, + // sets all children to be the TransformLayer's children, and sets that + // TransformLayer as the single child of this OpacityLayer. + void EnsureSingleChild(); + FML_DISALLOW_COPY_AND_ASSIGN(OpacityLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_OPACITY_LAYER_H_ diff --git a/flow/layers/performance_overlay_layer.cc b/flow/layers/performance_overlay_layer.cc index c80786e866e1b..ebb279c966866 100644 --- a/flow/layers/performance_overlay_layer.cc +++ b/flow/layers/performance_overlay_layer.cc @@ -9,19 +9,22 @@ #include "flutter/flow/layers/performance_overlay_layer.h" #include "third_party/skia/include/core/SkFont.h" -namespace flow { +namespace flutter { namespace { void DrawStatisticsText(SkCanvas& canvas, const std::string& string, int x, - int y) { + int y, + const std::string& font_path) { SkFont font; + if (font_path != "") { + font = SkFont(SkTypeface::MakeFromFile(font_path.c_str())); + } font.setSize(15); - font.setLinearMetrics(false); SkPaint paint; paint.setColor(SK_ColorGRAY); - canvas.drawSimpleText(string.c_str(), string.size(), kUTF8_SkTextEncoding, x, + canvas.drawSimpleText(string.c_str(), string.size(), SkTextEncoding::kUTF8, x, y, font, paint); } @@ -33,7 +36,8 @@ void VisualizeStopWatch(SkCanvas& canvas, SkScalar height, bool show_graph, bool show_labels, - const std::string& label_prefix) { + const std::string& label_prefix, + const std::string& font_path) { const int label_x = 8; // distance from x const int label_y = -10; // distance from y+height @@ -51,14 +55,20 @@ void VisualizeStopWatch(SkCanvas& canvas, stream << label_prefix << " " << "max " << max_ms_per_frame << " ms/frame, " << "avg " << average_ms_per_frame << " ms/frame"; - DrawStatisticsText(canvas, stream.str(), x + label_x, y + height + label_y); + DrawStatisticsText(canvas, stream.str(), x + label_x, y + height + label_y, + font_path); } } } // namespace -PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options) - : options_(options) {} +PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options, + const char* font_path) + : options_(options) { + if (font_path != nullptr) { + font_path_ = font_path; + } +} void PerformanceOverlayLayer::Paint(PaintContext& context) const { const int padding = 8; @@ -73,15 +83,15 @@ void PerformanceOverlayLayer::Paint(PaintContext& context) const { SkScalar height = paint_bounds().height() / 2; SkAutoCanvasRestore save(context.leaf_nodes_canvas, true); - VisualizeStopWatch(*context.leaf_nodes_canvas, context.frame_time, x, y, - width, height - padding, - options_ & kVisualizeRasterizerStatistics, - options_ & kDisplayRasterizerStatistics, "GPU"); + VisualizeStopWatch( + *context.leaf_nodes_canvas, context.raster_time, x, y, width, + height - padding, options_ & kVisualizeRasterizerStatistics, + options_ & kDisplayRasterizerStatistics, "GPU", font_path_); - VisualizeStopWatch(*context.leaf_nodes_canvas, context.engine_time, x, - y + height, width, height - padding, + VisualizeStopWatch(*context.leaf_nodes_canvas, context.ui_time, x, y + height, + width, height - padding, options_ & kVisualizeEngineStatistics, - options_ & kDisplayEngineStatistics, "UI"); + options_ & kDisplayEngineStatistics, "UI", font_path_); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/performance_overlay_layer.h b/flow/layers/performance_overlay_layer.h index b5f20ecbd7a6b..b5c3370d2055a 100644 --- a/flow/layers/performance_overlay_layer.h +++ b/flow/layers/performance_overlay_layer.h @@ -5,10 +5,12 @@ #ifndef FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_ #define FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_ +#include + #include "flutter/flow/layers/layer.h" #include "flutter/fml/macros.h" -namespace flow { +namespace flutter { const int kDisplayRasterizerStatistics = 1 << 0; const int kVisualizeRasterizerStatistics = 1 << 1; @@ -17,16 +19,18 @@ const int kVisualizeEngineStatistics = 1 << 3; class PerformanceOverlayLayer : public Layer { public: - explicit PerformanceOverlayLayer(uint64_t options); + explicit PerformanceOverlayLayer(uint64_t options, + const char* font_path = nullptr); void Paint(PaintContext& context) const override; private: int options_; + std::string font_path_; FML_DISALLOW_COPY_AND_ASSIGN(PerformanceOverlayLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_ diff --git a/flow/layers/performance_overlay_layer_unittests.cc b/flow/layers/performance_overlay_layer_unittests.cc new file mode 100644 index 0000000000000..6f9ba14610d99 --- /dev/null +++ b/flow/layers/performance_overlay_layer_unittests.cc @@ -0,0 +1,97 @@ +// 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. + +#include "flutter/flow/flow_test_utils.h" +#include "flutter/flow/layers/performance_overlay_layer.h" +#include "flutter/flow/raster_cache.h" + +#include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/utils/SkBase64.h" + +#include "gtest/gtest.h" + +// To get the size of kMockedTimes in compile time. +template +constexpr int size(const T (&array)[N]) noexcept { + return N; +} + +constexpr int kMockedTimes[] = {17, 1, 4, 24, 4, 25, 30, 4, 13, 34, + 14, 0, 18, 9, 32, 36, 26, 23, 5, 8, + 32, 18, 29, 16, 29, 18, 0, 36, 33, 10}; + +// Relative to the flutter/src/engine/flutter directory +const char* kGoldenFileName = "performance_overlay_gold.png"; + +// Relative to the flutter/src/engine/flutter directory +const char* kNewGoldenFileName = "performance_overlay_gold_new.png"; + +TEST(PerformanceOverlayLayer, Gold) { + const std::string& golden_dir = flutter::GetGoldenDir(); + // This unit test should only be run on Linux (not even on Mac since it's a + // golden test). Hence we don't have to worry about the "/" vs. "\". + std::string golden_file_path = golden_dir + "/" + kGoldenFileName; + std::string new_golden_file_path = golden_dir + "/" + kNewGoldenFileName; + + flutter::Stopwatch mock_stopwatch; + for (int i = 0; i < size(kMockedTimes); ++i) { + mock_stopwatch.SetLapTime( + fml::TimeDelta::FromMilliseconds(kMockedTimes[i])); + } + + const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); + sk_sp surface = SkSurface::MakeRaster(image_info); + + ASSERT_TRUE(surface != nullptr); + + flutter::TextureRegistry unused_texture_registry; + + flutter::Layer::PaintContext paintContext = { + nullptr, surface->getCanvas(), nullptr, nullptr, mock_stopwatch, + mock_stopwatch, unused_texture_registry, nullptr, false}; + + // Specify font file to ensure the same font across different operation + // systems. + flutter::PerformanceOverlayLayer layer( + flutter::kDisplayRasterizerStatistics | + flutter::kVisualizeRasterizerStatistics | + flutter::kDisplayEngineStatistics | + flutter::kVisualizeEngineStatistics, + flutter::GetFontFile().c_str()); + layer.set_paint_bounds(SkRect::MakeWH(1000, 400)); + surface->getCanvas()->clear(SK_ColorTRANSPARENT); + layer.Paint(paintContext); + + sk_sp snapshot = surface->makeImageSnapshot(); + sk_sp snapshot_data = snapshot->encodeToData(); + + sk_sp golden_data = + SkData::MakeFromFileName(golden_file_path.c_str()); + EXPECT_TRUE(golden_data != nullptr) + << "Golden file not found: " << golden_file_path << ".\n" + << "Please either set --golden-dir, or make sure that the unit test is " + << "run from the right directory (e.g., flutter/engine/src)."; + + const bool golden_data_matches = golden_data->equals(snapshot_data.get()); + if (!golden_data_matches) { + SkFILEWStream wstream(new_golden_file_path.c_str()); + wstream.write(snapshot_data->data(), snapshot_data->size()); + wstream.flush(); + + size_t b64_size = + SkBase64::Encode(snapshot_data->data(), snapshot_data->size(), nullptr); + sk_sp b64_data = SkData::MakeUninitialized(b64_size + 1); + char* b64_char = static_cast(b64_data->writable_data()); + SkBase64::Encode(snapshot_data->data(), snapshot_data->size(), b64_char); + b64_char[b64_size] = 0; // make it null terminated for printing + + EXPECT_TRUE(golden_data_matches) + << "Golden file mismatch. Please check " + << "the difference between " << kGoldenFileName << " and " + << kNewGoldenFileName << ", and replace the former " + << "with the latter if the difference looks good.\n\n" + << "See also the base64 encoded " << kNewGoldenFileName << ":\n" + << b64_char; + } +} diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index fc156802840b1..60902ea75ae4d 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -7,7 +7,10 @@ #include "flutter/flow/paint_utils.h" #include "third_party/skia/include/utils/SkShadowUtils.h" -namespace flow { +namespace flutter { + +const SkScalar kLightHeight = 600; +const SkScalar kLightRadius = 800; PhysicalShapeLayer::PhysicalShapeLayer(Clip clip_behavior) : isRect_(false), clip_behavior_(clip_behavior) {} @@ -40,8 +43,11 @@ void PhysicalShapeLayer::set_path(const SkPath& path) { void PhysicalShapeLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { + context->total_elevation += elevation_; + total_elevation_ = context->total_elevation; SkRect child_paint_bounds; PrerollChildren(context, matrix, &child_paint_bounds); + context->total_elevation -= elevation_; if (elevation_ == 0) { set_paint_bounds(path_.getBounds()); @@ -51,11 +57,46 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, set_needs_system_composite(true); #else // Add some margin to the paint bounds to leave space for the shadow. - // The margin is hardcoded to an arbitrary maximum for now because Skia - // doesn't provide a way to calculate it. We fill this whole region - // and clip children to it so we don't need to join the child paint bounds. + // We fill this whole region and clip children to it so we don't need to + // join the child paint bounds. + // The offset is calculated as follows: + + // .--- (kLightRadius) + // -------/ (light) + // | / + // | / + // |/ + // |O + // /| (kLightHeight) + // / | + // / | + // / | + // / | + // ------------- (layer) + // /| | + // / | | (elevation) + // A / | |B + // ------------------------------------------------ (canvas) + // --- (extent of shadow) + // + // E = lt } t = (r + w/2)/h + // } => + // r + w/2 = ht } E = (l/h)(r + w/2) + // + // Where: E = extent of shadow + // l = elevation of layer + // r = radius of the light source + // w = width of the layer + // h = light height + // t = tangent of AOB, i.e., multiplier for elevation to extent SkRect bounds(path_.getBounds()); - bounds.outset(20.0, 20.0); + // tangent for x + double tx = (kLightRadius * device_pixel_ratio_ + bounds.width() * 0.5) / + kLightHeight; + // tangent for y + double ty = (kLightRadius * device_pixel_ratio_ + bounds.height() * 0.5) / + kLightHeight; + bounds.outset(elevation_ * tx, elevation_ * ty); set_paint_bounds(bounds); #endif // defined(OS_FUCHSIA) } @@ -66,7 +107,21 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, void PhysicalShapeLayer::UpdateScene(SceneUpdateContext& context) { FML_DCHECK(needs_system_composite()); - SceneUpdateContext::Frame frame(context, frameRRect_, color_, elevation_); + // Retained rendering: speedup by reusing a retained entity node if possible. + // When an entity node is reused, no paint layer is added to the frame so we + // won't call PhysicalShapeLayer::Paint. + LayerRasterCacheKey key(unique_id(), context.Matrix()); + if (context.HasRetainedNode(key)) { + const scenic::EntityNode& retained_node = context.GetRetainedNode(key); + FML_DCHECK(context.top_entity()); + FML_DCHECK(retained_node.session() == context.session()); + context.top_entity()->entity_node().AddChild(retained_node); + return; + } + + // If we can't find an existing retained surface, create one. + SceneUpdateContext::Frame frame(context, frameRRect_, color_, elevation_, + total_elevation_, viewport_depth_, this); for (auto& layer : layers()) { if (layer->needs_painting()) { frame.AddPaintLayer(layer.get()); @@ -90,6 +145,7 @@ void PhysicalShapeLayer::Paint(PaintContext& context) const { // Call drawPath without clip if possible for better performance. SkPaint paint; paint.setColor(color_); + paint.setAntiAlias(true); if (clip_behavior_ != Clip::antiAliasWithSaveLayer) { context.leaf_nodes_canvas->drawPath(path_, paint); } @@ -131,8 +187,6 @@ void PhysicalShapeLayer::DrawShadow(SkCanvas* canvas, SkScalar dpr) { const SkScalar kAmbientAlpha = 0.039f; const SkScalar kSpotAlpha = 0.25f; - const SkScalar kLightHeight = 600; - const SkScalar kLightRadius = 800; SkShadowFlags flags = transparentOccluder ? SkShadowFlags::kTransparentOccluder_ShadowFlag @@ -151,4 +205,4 @@ void PhysicalShapeLayer::DrawShadow(SkCanvas* canvas, dpr * kLightRadius, ambientColor, spotColor, flags); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/physical_shape_layer.h b/flow/layers/physical_shape_layer.h index 45ba68e86d9b3..edfbd410c2851 100644 --- a/flow/layers/physical_shape_layer.h +++ b/flow/layers/physical_shape_layer.h @@ -7,7 +7,7 @@ #include "flutter/flow/layers/container_layer.h" -namespace flow { +namespace flutter { class PhysicalShapeLayer : public ContainerLayer { public: @@ -16,10 +16,15 @@ class PhysicalShapeLayer : public ContainerLayer { void set_path(const SkPath& path); - void set_elevation(float elevation) { elevation_ = elevation; } void set_color(SkColor color) { color_ = color; } void set_shadow_color(SkColor shadow_color) { shadow_color_ = shadow_color; } void set_device_pixel_ratio(SkScalar dpr) { device_pixel_ratio_ = dpr; } + void set_viewport_depth(float depth) { viewport_depth_ = depth; } + + // Sets the elevation. This needs to be set before preroll because it's then + // cached by any children of this layer. Setting it after preroll will break + // their elevation calculations. + void set_elevation(float elevation) { elevation_ = elevation; } static void DrawShadow(SkCanvas* canvas, const SkPath& path, @@ -37,7 +42,9 @@ class PhysicalShapeLayer : public ContainerLayer { #endif // defined(OS_FUCHSIA) private: - float elevation_; + float elevation_ = 0.0f; + float total_elevation_ = 0.0f; + float viewport_depth_; SkColor color_; SkColor shadow_color_; SkScalar device_pixel_ratio_; @@ -45,8 +52,10 @@ class PhysicalShapeLayer : public ContainerLayer { bool isRect_; SkRRect frameRRect_; Clip clip_behavior_; + + friend class PhysicalShapeLayer_TotalElevation_Test; }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_ diff --git a/flow/layers/physical_shape_layer_unittests.cc b/flow/layers/physical_shape_layer_unittests.cc new file mode 100644 index 0000000000000..6dd6c97094899 --- /dev/null +++ b/flow/layers/physical_shape_layer_unittests.cc @@ -0,0 +1,60 @@ +// 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. + +#include "flutter/flow/layers/physical_shape_layer.h" + +#include "gtest/gtest.h" + +namespace flutter { + +TEST(PhysicalShapeLayer, TotalElevation) { + std::shared_ptr layers[4]; + + for (int i = 0; i < 4; i += 1) { + layers[i] = std::make_shared(Clip::none); + layers[i]->set_elevation((float)(i + 1)); + } + + layers[0]->Add(layers[1]); + layers[0]->Add(layers[2]); + layers[2]->Add(layers[3]); + + const Stopwatch unused_stopwatch; + TextureRegistry unused_texture_registry; + PrerollContext preroll_context{ + nullptr, // raster_cache (don't consult the cache) + nullptr, // gr_context (used for the raster cache) + nullptr, // external view embedder + nullptr, // SkColorSpace* dst_color_space + kGiantRect, // SkRect cull_rect + unused_stopwatch, // frame time (dont care) + unused_stopwatch, // engine time (dont care) + unused_texture_registry, // texture registry (not supported) + false, // checkerboard_offscreen_layers + 0.0f, // total elevation + }; + + SkMatrix identity; + identity.setIdentity(); + + layers[0]->Preroll(&preroll_context, identity); + + // It should look like this: + // layers[0] +1.0f + // | \ + // | \ + // | \ + // | layers[2] +3.0f + // | | + // | layers[3] +4.0f + // | + // | + // layers[1] + 2.0f + EXPECT_EQ(layers[0]->total_elevation_, 1.0f); + EXPECT_EQ(layers[1]->total_elevation_, 3.0f); + EXPECT_EQ(layers[2]->total_elevation_, 4.0f); + EXPECT_EQ(layers[3]->total_elevation_, 8.0f); +} + +} // namespace flutter diff --git a/flow/layers/picture_layer.cc b/flow/layers/picture_layer.cc index cef3321df4d19..fc932a5351997 100644 --- a/flow/layers/picture_layer.cc +++ b/flow/layers/picture_layer.cc @@ -6,7 +6,7 @@ #include "flutter/fml/logging.h" -namespace flow { +namespace flutter { PictureLayer::PictureLayer() = default; @@ -52,4 +52,4 @@ void PictureLayer::Paint(PaintContext& context) const { context.leaf_nodes_canvas->drawPicture(picture()); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/picture_layer.h b/flow/layers/picture_layer.h index fc50e8f3bf6dd..88ea2f78df5e5 100644 --- a/flow/layers/picture_layer.h +++ b/flow/layers/picture_layer.h @@ -11,7 +11,7 @@ #include "flutter/flow/raster_cache.h" #include "flutter/flow/skia_gpu_object.h" -namespace flow { +namespace flutter { class PictureLayer : public Layer { public: @@ -43,6 +43,6 @@ class PictureLayer : public Layer { FML_DISALLOW_COPY_AND_ASSIGN(PictureLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_PICTURE_LAYER_H_ diff --git a/flow/layers/platform_view_layer.cc b/flow/layers/platform_view_layer.cc index d10bd2ac4f309..0c9741c474cdf 100644 --- a/flow/layers/platform_view_layer.cc +++ b/flow/layers/platform_view_layer.cc @@ -4,7 +4,7 @@ #include "flutter/flow/layers/platform_view_layer.h" -namespace flow { +namespace flutter { PlatformViewLayer::PlatformViewLayer() = default; @@ -39,4 +39,4 @@ void PlatformViewLayer::Paint(PaintContext& context) const { context.view_embedder->CompositeEmbeddedView(view_id_, params); context.leaf_nodes_canvas = canvas; } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/platform_view_layer.h b/flow/layers/platform_view_layer.h index f3e0c48449caf..02309f7fbc2d9 100644 --- a/flow/layers/platform_view_layer.h +++ b/flow/layers/platform_view_layer.h @@ -9,7 +9,7 @@ #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkSize.h" -namespace flow { +namespace flutter { class PlatformViewLayer : public Layer { public: @@ -31,6 +31,6 @@ class PlatformViewLayer : public Layer { FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_PLATFORM_VIEW_LAYER_H_ diff --git a/flow/layers/shader_mask_layer.cc b/flow/layers/shader_mask_layer.cc index 5c13f56e8b9a1..d73a65f8a4ebe 100644 --- a/flow/layers/shader_mask_layer.cc +++ b/flow/layers/shader_mask_layer.cc @@ -4,7 +4,7 @@ #include "flutter/flow/layers/shader_mask_layer.h" -namespace flow { +namespace flutter { ShaderMaskLayer::ShaderMaskLayer() = default; @@ -26,4 +26,4 @@ void ShaderMaskLayer::Paint(PaintContext& context) const { SkRect::MakeWH(mask_rect_.width(), mask_rect_.height()), paint); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/shader_mask_layer.h b/flow/layers/shader_mask_layer.h index 2b4b3f052ae7b..12f5439be5740 100644 --- a/flow/layers/shader_mask_layer.h +++ b/flow/layers/shader_mask_layer.h @@ -9,7 +9,7 @@ #include "third_party/skia/include/core/SkShader.h" -namespace flow { +namespace flutter { class ShaderMaskLayer : public ContainerLayer { public: @@ -32,6 +32,6 @@ class ShaderMaskLayer : public ContainerLayer { FML_DISALLOW_COPY_AND_ASSIGN(ShaderMaskLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_SHADER_MASK_LAYER_H_ diff --git a/flow/layers/texture_layer.cc b/flow/layers/texture_layer.cc index df845caf80215..2703940f5fbc2 100644 --- a/flow/layers/texture_layer.cc +++ b/flow/layers/texture_layer.cc @@ -6,7 +6,7 @@ #include "flutter/flow/texture.h" -namespace flow { +namespace flutter { TextureLayer::TextureLayer() = default; @@ -23,7 +23,8 @@ void TextureLayer::Paint(PaintContext& context) const { if (!texture) { return; } - texture->Paint(*context.leaf_nodes_canvas, paint_bounds(), freeze_); + texture->Paint(*context.leaf_nodes_canvas, paint_bounds(), freeze_, + context.gr_context); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/texture_layer.h b/flow/layers/texture_layer.h index f761b5d02d053..dd77630e2f971 100644 --- a/flow/layers/texture_layer.h +++ b/flow/layers/texture_layer.h @@ -9,7 +9,7 @@ #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkSize.h" -namespace flow { +namespace flutter { class TextureLayer : public Layer { public: @@ -33,6 +33,6 @@ class TextureLayer : public Layer { FML_DISALLOW_COPY_AND_ASSIGN(TextureLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_TEXTURE_LAYER_H_ diff --git a/flow/layers/transform_layer.cc b/flow/layers/transform_layer.cc index 8abb550b95935..37d5b606258fe 100644 --- a/flow/layers/transform_layer.cc +++ b/flow/layers/transform_layer.cc @@ -4,19 +4,37 @@ #include "flutter/flow/layers/transform_layer.h" -namespace flow { +namespace flutter { -TransformLayer::TransformLayer() = default; +TransformLayer::TransformLayer() { + transform_.setIdentity(); +} TransformLayer::~TransformLayer() = default; void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { + // Checks (in some degree) that SkMatrix transform_ is valid and initialized. + // + // We need this even if transform_ is initialized to identity since one can + // call set_transform with an uninitialized SkMatrix. + // + // If transform_ is uninitialized, this assert may look flaky as it doesn't + // fail all the time, and some rerun may make it pass. But don't ignore it and + // just rerun the test if this is triggered, since even a flaky failure here + // may signify a potentially big problem in the code. + // + // We have to write this flaky test because there is no reliable way to test + // whether a variable is initialized or not in C++. + FML_CHECK(transform_.isFinite()); + SkMatrix child_matrix; child_matrix.setConcat(matrix, transform_); SkRect previous_cull_rect = context->cull_rect; SkMatrix inverse_transform_; - if (transform_.invert(&inverse_transform_)) { + // Perspective projections don't produce rectangles that are useful for + // culling for some reason. + if (!transform_.hasPerspective() && transform_.invert(&inverse_transform_)) { inverse_transform_.mapRect(&context->cull_rect); } else { context->cull_rect = kGiantRect; @@ -51,4 +69,4 @@ void TransformLayer::Paint(PaintContext& context) const { PaintChildren(context); } -} // namespace flow +} // namespace flutter diff --git a/flow/layers/transform_layer.h b/flow/layers/transform_layer.h index b1fb830bf2b9d..ef72f969d8f29 100644 --- a/flow/layers/transform_layer.h +++ b/flow/layers/transform_layer.h @@ -7,8 +7,10 @@ #include "flutter/flow/layers/container_layer.h" -namespace flow { +namespace flutter { +// Be careful that SkMatrix's default constructor doesn't initialize the matrix +// at all. Hence |set_transform| must be called with an initialized SkMatrix. class TransformLayer : public ContainerLayer { public: TransformLayer(); @@ -30,6 +32,6 @@ class TransformLayer : public ContainerLayer { FML_DISALLOW_COPY_AND_ASSIGN(TransformLayer); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_LAYERS_TRANSFORM_LAYER_H_ diff --git a/flow/matrix_decomposition.cc b/flow/matrix_decomposition.cc index c710908dc651c..1935393906513 100644 --- a/flow/matrix_decomposition.cc +++ b/flow/matrix_decomposition.cc @@ -4,7 +4,7 @@ #include "flutter/flow/matrix_decomposition.h" -namespace flow { +namespace flutter { static inline SkVector3 SkVector3Combine(const SkVector3& a, float a_scale, @@ -151,4 +151,4 @@ bool MatrixDecomposition::IsValid() const { return valid_; } -} // namespace flow +} // namespace flutter diff --git a/flow/matrix_decomposition.h b/flow/matrix_decomposition.h index 2cf3c0faa4298..81794c2fe589f 100644 --- a/flow/matrix_decomposition.h +++ b/flow/matrix_decomposition.h @@ -10,7 +10,7 @@ #include "third_party/skia/include/core/SkMatrix44.h" #include "third_party/skia/include/core/SkPoint3.h" -namespace flow { +namespace flutter { /// Decomposes a given non-degenerate transformation matrix into a sequence of /// operations that produced it. The validity of the decomposition must always @@ -46,6 +46,6 @@ class MatrixDecomposition { FML_DISALLOW_COPY_AND_ASSIGN(MatrixDecomposition); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_MATRIX_DECOMPOSITION_H_ diff --git a/flow/matrix_decomposition_unittests.cc b/flow/matrix_decomposition_unittests.cc index 6c2ba6737372d..cf96025276737 100644 --- a/flow/matrix_decomposition_unittests.cc +++ b/flow/matrix_decomposition_unittests.cc @@ -18,7 +18,7 @@ TEST(MatrixDecomposition, Rotation) { const auto angle = M_PI_4; matrix.setRotateAbout(0.0, 0.0, 1.0, angle); - flow::MatrixDecomposition decomposition(matrix); + flutter::MatrixDecomposition decomposition(matrix); ASSERT_TRUE(decomposition.IsValid()); const auto sine = sin(angle * 0.5); @@ -35,7 +35,7 @@ TEST(MatrixDecomposition, Scale) { const auto scale = 5.0; matrix.setScale(scale + 0, scale + 1, scale + 2); - flow::MatrixDecomposition decomposition(matrix); + flutter::MatrixDecomposition decomposition(matrix); ASSERT_TRUE(decomposition.IsValid()); ASSERT_FLOAT_EQ(scale + 0, decomposition.scale().fX); @@ -49,7 +49,7 @@ TEST(MatrixDecomposition, Translate) { const auto translate = 125.0; matrix.setTranslate(translate + 0, translate + 1, translate + 2); - flow::MatrixDecomposition decomposition(matrix); + flutter::MatrixDecomposition decomposition(matrix); ASSERT_TRUE(decomposition.IsValid()); ASSERT_FLOAT_EQ(translate + 0, decomposition.translation().fX); @@ -58,8 +58,6 @@ TEST(MatrixDecomposition, Translate) { } TEST(MatrixDecomposition, Combination) { - SkMatrix44 matrix = SkMatrix44::I(); - const auto rotation = M_PI_4; const auto scale = 5; const auto translate = 125.0; @@ -75,7 +73,7 @@ TEST(MatrixDecomposition, Combination) { SkMatrix44 combined = m3 * m2 * m1; - flow::MatrixDecomposition decomposition(combined); + flutter::MatrixDecomposition decomposition(combined); ASSERT_TRUE(decomposition.IsValid()); ASSERT_FLOAT_EQ(translate, decomposition.translation().fX); @@ -99,7 +97,7 @@ TEST(MatrixDecomposition, ScaleFloatError) { SkMatrix44 matrix = SkMatrix44::I(); matrix.setScale(scale, scale, 1.0f); - flow::MatrixDecomposition decomposition3(matrix); + flutter::MatrixDecomposition decomposition3(matrix); ASSERT_TRUE(decomposition3.IsValid()); ASSERT_FLOAT_EQ(scale, decomposition3.scale().fX); @@ -124,13 +122,13 @@ TEST(MatrixDecomposition, ScaleFloatError) { SkMatrix44 matrix3 = SkMatrix44::I(); matrix3.setScale(scale3, scale3, 1.f); - flow::MatrixDecomposition decomposition(matrix); + flutter::MatrixDecomposition decomposition(matrix); ASSERT_TRUE(decomposition.IsValid()); - flow::MatrixDecomposition decomposition2(matrix2); + flutter::MatrixDecomposition decomposition2(matrix2); ASSERT_TRUE(decomposition2.IsValid()); - flow::MatrixDecomposition decomposition3(matrix3); + flutter::MatrixDecomposition decomposition3(matrix3); ASSERT_TRUE(decomposition3.IsValid()); ASSERT_FLOAT_EQ(scale, decomposition.scale().fX); diff --git a/flow/paint_utils.cc b/flow/paint_utils.cc index 22b0735b8939f..38fc17979a0c3 100644 --- a/flow/paint_utils.cc +++ b/flow/paint_utils.cc @@ -10,7 +10,7 @@ #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkShader.h" -namespace flow { +namespace flutter { namespace { @@ -20,8 +20,7 @@ sk_sp CreateCheckerboardShader(SkColor c1, SkColor c2, int size) { bm.eraseColor(c1); bm.eraseArea(SkIRect::MakeLTRB(0, 0, size, size), c2); bm.eraseArea(SkIRect::MakeLTRB(size, size, 2 * size, 2 * size), c2); - return SkShader::MakeBitmapShader(bm, SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); + return bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat); } } // anonymous namespace @@ -51,4 +50,4 @@ void DrawCheckerboard(SkCanvas* canvas, const SkRect& rect) { canvas->drawRect(rect, debugPaint); } -} // namespace flow +} // namespace flutter diff --git a/flow/paint_utils.h b/flow/paint_utils.h index 352dee124fc91..c6bfccedbd317 100644 --- a/flow/paint_utils.h +++ b/flow/paint_utils.h @@ -9,12 +9,12 @@ #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkRect.h" -namespace flow { +namespace flutter { void DrawCheckerboard(SkCanvas* canvas, SkColor c1, SkColor c2, int size); void DrawCheckerboard(SkCanvas* canvas, const SkRect& rect); -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_PAINT_UTILS_H_ diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc index 0827a2de405e9..4ad18adf172e4 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -15,7 +15,7 @@ #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkSurface.h" -namespace flow { +namespace flutter { RasterCacheResult::RasterCacheResult() {} @@ -36,8 +36,12 @@ void RasterCacheResult::draw(SkCanvas& canvas, const SkPaint* paint) const { canvas.drawImage(image_, bounds.fLeft, bounds.fTop, paint); } -RasterCache::RasterCache(size_t threshold) - : threshold_(threshold), checkerboard_images_(false), weak_factory_(this) {} +RasterCache::RasterCache(size_t access_threshold, + size_t picture_cache_limit_per_frame) + : access_threshold_(access_threshold), + picture_cache_limit_per_frame_(picture_cache_limit_per_frame), + checkerboard_images_(false), + weak_factory_(this) {} RasterCache::~RasterCache() = default; @@ -84,7 +88,7 @@ static bool IsPictureWorthRasterizing(SkPicture* picture, // TODO(abarth): We should find a better heuristic here that lets us avoid // wasting memory on trivial layers that are easy to re-rasterize every frame. - return picture->approximateOpCount() > 10; + return picture->approximateOpCount() > 5; } static RasterCacheResult Rasterize( @@ -94,6 +98,7 @@ static RasterCacheResult Rasterize( bool checkerboard, const SkRect& logical_rect, std::function draw_function) { + TRACE_EVENT0("flutter", "RasterCachePopulate"); SkIRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm); const SkImageInfo image_info = SkImageInfo::MakeN32Premul( @@ -126,8 +131,6 @@ RasterCacheResult RasterizePicture(SkPicture* picture, const SkMatrix& ctm, SkColorSpace* dst_color_space, bool checkerboard) { - TRACE_EVENT0("flutter", "RasterCachePopulate"); - return Rasterize(context, ctm, dst_color_space, checkerboard, picture->cullRect(), [=](SkCanvas* canvas) { canvas->drawPicture(picture); }); @@ -148,9 +151,9 @@ static inline size_t ClampSize(size_t value, size_t min, size_t max) { void RasterCache::Prepare(PrerollContext* context, Layer* layer, const SkMatrix& ctm) { - LayerRasterCacheKey cache_key(layer, ctm); + LayerRasterCacheKey cache_key(layer->unique_id(), ctm); Entry& entry = layer_cache_[cache_key]; - entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_); + entry.access_count = ClampSize(entry.access_count + 1, 0, access_threshold_); entry.used_this_frame = true; if (!entry.image.is_valid()) { entry.image = Rasterize(context->gr_context, ctm, context->dst_color_space, @@ -163,9 +166,10 @@ void RasterCache::Prepare(PrerollContext* context, Layer::PaintContext paintContext = { (SkCanvas*)&internal_nodes_canvas, canvas, + context->gr_context, nullptr, - context->frame_time, - context->engine_time, + context->raster_time, + context->ui_time, context->texture_registry, context->raster_cache, context->checkerboard_offscreen_layers}; @@ -182,6 +186,9 @@ bool RasterCache::Prepare(GrContext* context, SkColorSpace* dst_color_space, bool is_complex, bool will_change) { + if (picture_cached_this_frame_ >= picture_cache_limit_per_frame_) { + return false; + } if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) { // We only deal with pictures that are worthy of rasterization. return false; @@ -199,10 +206,10 @@ bool RasterCache::Prepare(GrContext* context, PictureRasterCacheKey cache_key(picture->uniqueID(), transformation_matrix); Entry& entry = picture_cache_[cache_key]; - entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_); + entry.access_count = ClampSize(entry.access_count + 1, 0, access_threshold_); entry.used_this_frame = true; - if (entry.access_count < threshold_ || threshold_ == 0) { + if (entry.access_count < access_threshold_ || access_threshold_ == 0) { // Frame threshold has not yet been reached. return false; } @@ -211,6 +218,7 @@ bool RasterCache::Prepare(GrContext* context, entry.image = RasterizePicture(picture, context, transformation_matrix, dst_color_space, checkerboard_images_); } + picture_cached_this_frame_++; return true; } @@ -222,7 +230,7 @@ RasterCacheResult RasterCache::Get(const SkPicture& picture, } RasterCacheResult RasterCache::Get(Layer* layer, const SkMatrix& ctm) const { - LayerRasterCacheKey cache_key(layer, ctm); + LayerRasterCacheKey cache_key(layer->unique_id(), ctm); auto it = layer_cache_.find(cache_key); return it == layer_cache_.end() ? RasterCacheResult() : it->second.image; } @@ -232,6 +240,8 @@ void RasterCache::SweepAfterFrame() { using LayerCache = LayerRasterCacheKey::Map; SweepOneCacheAfterFrame(picture_cache_); SweepOneCacheAfterFrame(layer_cache_); + picture_cached_this_frame_ = 0; + TraceStatsToTimeline(); } void RasterCache::Clear() { @@ -251,4 +261,35 @@ void RasterCache::SetCheckboardCacheImages(bool checkerboard) { Clear(); } -} // namespace flow +void RasterCache::TraceStatsToTimeline() const { +#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE + + size_t layer_cache_count = 0; + size_t layer_cache_bytes = 0; + size_t picture_cache_count = 0; + size_t picture_cache_bytes = 0; + + for (const auto& item : layer_cache_) { + const auto dimensions = item.second.image.image_dimensions(); + layer_cache_count++; + layer_cache_bytes += dimensions.width() * dimensions.height() * 4; + } + + for (const auto& item : picture_cache_) { + const auto dimensions = item.second.image.image_dimensions(); + picture_cache_count++; + picture_cache_bytes += dimensions.width() * dimensions.height() * 4; + } + + FML_TRACE_COUNTER("flutter", "RasterCache", + reinterpret_cast(this), // + "LayerCount", layer_cache_count, // + "LayerMBytes", layer_cache_bytes * 1e-6, // + "PictureCount", picture_cache_count, // + "PictureMBytes", picture_cache_bytes * 1e-6 // + ); + +#endif // FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE +} + +} // namespace flutter diff --git a/flow/raster_cache.h b/flow/raster_cache.h index cb4383f41fb52..f008f2459cc30 100644 --- a/flow/raster_cache.h +++ b/flow/raster_cache.h @@ -15,7 +15,7 @@ #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkSize.h" -namespace flow { +namespace flutter { class RasterCacheResult { public: @@ -33,6 +33,10 @@ class RasterCacheResult { void draw(SkCanvas& canvas, const SkPaint* paint = nullptr) const; + SkISize image_dimensions() const { + return image_ ? image_->dimensions() : SkISize::Make(0, 0); + }; + private: sk_sp image_; SkRect logical_rect_; @@ -42,7 +46,15 @@ struct PrerollContext; class RasterCache { public: - explicit RasterCache(size_t threshold = 3); + // The default max number of picture raster caches to be generated per frame. + // Generating too many caches in one frame may cause jank on that frame. This + // limit allows us to throttle the cache and distribute the work across + // multiple frames. + static constexpr int kDefaultPictureCacheLimitPerFrame = 3; + + explicit RasterCache( + size_t access_threshold = 3, + size_t picture_cache_limit_per_frame = kDefaultPictureCacheLimitPerFrame); ~RasterCache(); @@ -67,6 +79,8 @@ class RasterCache { // 1. The picture is not worth rasterizing // 2. The matrix is singular // 3. The picture is accessed too few times + // 4. There are too many pictures to be cached in the current frame. + // (See also kDefaultPictureCacheLimitPerFrame.) bool Prepare(GrContext* context, SkPicture* picture, const SkMatrix& transformation_matrix, @@ -77,6 +91,7 @@ class RasterCache { void Prepare(PrerollContext* context, Layer* layer, const SkMatrix& ctm); RasterCacheResult Get(const SkPicture& picture, const SkMatrix& ctm) const; + RasterCacheResult Get(Layer* layer, const SkMatrix& ctm) const; void SweepAfterFrame(); @@ -109,15 +124,19 @@ class RasterCache { } } - const size_t threshold_; + const size_t access_threshold_; + const size_t picture_cache_limit_per_frame_; + size_t picture_cached_this_frame_ = 0; PictureRasterCacheKey::Map picture_cache_; LayerRasterCacheKey::Map layer_cache_; bool checkerboard_images_; fml::WeakPtrFactory weak_factory_; + void TraceStatsToTimeline() const; + FML_DISALLOW_COPY_AND_ASSIGN(RasterCache); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_RASTER_CACHE_H_ diff --git a/flow/raster_cache_key.cc b/flow/raster_cache_key.cc index 4dfef752f6974..0a20cde72dcc6 100644 --- a/flow/raster_cache_key.cc +++ b/flow/raster_cache_key.cc @@ -4,8 +4,8 @@ #include "flutter/flow/raster_cache_key.h" -namespace flow { +namespace flutter { // -} // namespace flow +} // namespace flutter diff --git a/flow/raster_cache_key.h b/flow/raster_cache_key.h index 5fb6cc279c511..5eae4d3dccacb 100644 --- a/flow/raster_cache_key.h +++ b/flow/raster_cache_key.h @@ -9,7 +9,7 @@ #include "flutter/flow/matrix_decomposition.h" #include "flutter/fml/logging.h" -namespace flow { +namespace flutter { template class RasterCacheKey { @@ -56,8 +56,9 @@ using PictureRasterCacheKey = RasterCacheKey; class Layer; -using LayerRasterCacheKey = RasterCacheKey; +// The ID is the uint64_t layer unique_id +using LayerRasterCacheKey = RasterCacheKey; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_RASTER_CACHE_KEY_H_ diff --git a/flow/raster_cache_unittests.cc b/flow/raster_cache_unittests.cc index 3fd73d5bca55e..64f4405ebe5a0 100644 --- a/flow/raster_cache_unittests.cc +++ b/flow/raster_cache_unittests.cc @@ -18,13 +18,13 @@ sk_sp GetSamplePicture() { } TEST(RasterCache, SimpleInitialization) { - flow::RasterCache cache; + flutter::RasterCache cache; ASSERT_TRUE(true); } TEST(RasterCache, ThresholdIsRespected) { size_t threshold = 3; - flow::RasterCache cache(threshold); + flutter::RasterCache cache(threshold); SkMatrix matrix = SkMatrix::I(); @@ -46,7 +46,7 @@ TEST(RasterCache, ThresholdIsRespected) { TEST(RasterCache, ThresholdIsRespectedWhenZero) { size_t threshold = 0; - flow::RasterCache cache(threshold); + flutter::RasterCache cache(threshold); SkMatrix matrix = SkMatrix::I(); @@ -68,7 +68,7 @@ TEST(RasterCache, ThresholdIsRespectedWhenZero) { TEST(RasterCache, SweepsRemoveUnusedFrames) { size_t threshold = 3; - flow::RasterCache cache(threshold); + flutter::RasterCache cache(threshold); SkMatrix matrix = SkMatrix::I(); diff --git a/flow/scene_update_context.cc b/flow/scene_update_context.cc index e5e4bac42cfad..4f07edd43dd3c 100644 --- a/flow/scene_update_context.cc +++ b/flow/scene_update_context.cc @@ -4,12 +4,50 @@ #include "flutter/flow/scene_update_context.h" -#include "flutter/flow/export_node.h" #include "flutter/flow/layers/layer.h" #include "flutter/flow/matrix_decomposition.h" #include "flutter/fml/trace_event.h" -namespace flow { +namespace flutter { + +// Helper function to generate clip planes for a scenic::EntityNode. +static void SetEntityNodeClipPlanes(scenic::EntityNode* entity_node, + const SkRect& bounds) { + const float top = bounds.top(); + const float bottom = bounds.bottom(); + const float left = bounds.left(); + const float right = bounds.right(); + + // We will generate 4 oriented planes, one for each edge of the bounding rect. + std::vector clip_planes; + clip_planes.resize(4); + + // Top plane. + clip_planes[0].dist = top; + clip_planes[0].dir.x = 0.f; + clip_planes[0].dir.y = 1.f; + clip_planes[0].dir.z = 0.f; + + // Bottom plane. + clip_planes[1].dist = -bottom; + clip_planes[1].dir.x = 0.f; + clip_planes[1].dir.y = -1.f; + clip_planes[1].dir.z = 0.f; + + // Left plane. + clip_planes[2].dist = left; + clip_planes[2].dir.x = 1.f; + clip_planes[2].dir.y = 0.f; + clip_planes[2].dir.z = 0.f; + + // Right plane. + clip_planes[3].dist = -right; + clip_planes[3].dir.x = -1.f; + clip_planes[3].dir.y = 0.f; + clip_planes[3].dir.z = 0.f; + + entity_node->SetClipPlanes(std::move(clip_planes)); +} SceneUpdateContext::SceneUpdateContext(scenic::Session* session, SurfaceProducer* surface_producer) @@ -17,36 +55,18 @@ SceneUpdateContext::SceneUpdateContext(scenic::Session* session, FML_DCHECK(surface_producer_ != nullptr); } -SceneUpdateContext::~SceneUpdateContext() { - // Release Mozart session resources for all ExportNodes. - for (auto export_node : export_nodes_) { - export_node->Dispose(false); - } -}; - -void SceneUpdateContext::AddChildScene(ExportNode* export_node, - SkPoint offset, - bool hit_testable) { - FML_DCHECK(top_entity_); - - export_node->Bind(*this, top_entity_->entity_node(), offset, hit_testable); -} - -void SceneUpdateContext::AddExportNode(ExportNode* export_node) { - export_nodes_.insert(export_node); // Might already have been added. -} - -void SceneUpdateContext::RemoveExportNode(ExportNode* export_node) { - export_nodes_.erase(export_node); -} - -void SceneUpdateContext::CreateFrame(scenic::EntityNode& entity_node, - const SkRRect& rrect, - SkColor color, - const SkRect& paint_bounds, - std::vector paint_layers) { +void SceneUpdateContext::CreateFrame( + std::unique_ptr entity_node, + std::unique_ptr shape_node, + const SkRRect& rrect, + SkColor color, + const SkRect& paint_bounds, + std::vector paint_layers, + Layer* layer) { // Frames always clip their children. - entity_node.SetClip(0u, true /* clip to self */); + SetEntityNodeClipPlanes(entity_node.get(), rrect.getBounds()); + // TODO(SCN-1274): AddPart() and SetClip() will be deleted. + entity_node->SetClip(0u, true /* clip to self */); // We don't need a shape if the frame is zero size. if (rrect.isEmpty()) @@ -54,7 +74,7 @@ void SceneUpdateContext::CreateFrame(scenic::EntityNode& entity_node, // Add a part which represents the frame's geometry for clipping purposes // and possibly for its texture. - // TODO(MZ-137): Need to be able to express the radii as vectors. + // TODO(SCN-137): Need to be able to express the radii as vectors. SkRect shape_bounds = rrect.getBounds(); scenic::RoundedRectangle shape( session_, // session @@ -65,12 +85,10 @@ void SceneUpdateContext::CreateFrame(scenic::EntityNode& entity_node, rrect.radii(SkRRect::kLowerRight_Corner).x(), // bottom_right_radius rrect.radii(SkRRect::kLowerLeft_Corner).x() // bottom_left_radius ); - scenic::ShapeNode shape_node(session_); - shape_node.SetShape(shape); - shape_node.SetTranslation(shape_bounds.width() * 0.5f + shape_bounds.left(), - shape_bounds.height() * 0.5f + shape_bounds.top(), - 0.f); - entity_node.AddPart(shape_node); + shape_node->SetShape(shape); + shape_node->SetTranslation(shape_bounds.width() * 0.5f + shape_bounds.left(), + shape_bounds.height() * 0.5f + shape_bounds.top(), + 0.f); // Check whether the painted layers will be visible. if (paint_bounds.isEmpty() || !paint_bounds.intersects(shape_bounds)) @@ -78,37 +96,18 @@ void SceneUpdateContext::CreateFrame(scenic::EntityNode& entity_node, // Check whether a solid color will suffice. if (paint_layers.empty()) { - SetShapeColor(shape_node, color); + SetShapeColor(*shape_node, color); return; } // Apply current metrics and transformation scale factors. - const float scale_x = metrics_->scale_x * top_scale_x_; - const float scale_y = metrics_->scale_y * top_scale_y_; - - // If the painted area only covers a portion of the frame then we can - // reduce the texture size by drawing just that smaller area. - SkRect inner_bounds = shape_bounds; - inner_bounds.intersect(paint_bounds); - if (inner_bounds != shape_bounds && rrect.contains(inner_bounds)) { - SetShapeColor(shape_node, color); - - scenic::Rectangle inner_shape(session_, inner_bounds.width(), - inner_bounds.height()); - scenic::ShapeNode inner_node(session_); - inner_node.SetShape(inner_shape); - inner_node.SetTranslation(inner_bounds.width() * 0.5f + inner_bounds.left(), - inner_bounds.height() * 0.5f + inner_bounds.top(), - 0.f); - entity_node.AddPart(inner_node); - SetShapeTextureOrColor(inner_node, color, scale_x, scale_y, inner_bounds, - std::move(paint_layers)); - return; - } + const float scale_x = ScaleX(); + const float scale_y = ScaleY(); // Apply a texture to the whole shape. - SetShapeTextureOrColor(shape_node, color, scale_x, scale_y, shape_bounds, - std::move(paint_layers)); + SetShapeTextureOrColor(*shape_node, color, scale_x, scale_y, shape_bounds, + std::move(paint_layers), layer, + std::move(entity_node)); } void SceneUpdateContext::SetShapeTextureOrColor( @@ -117,9 +116,12 @@ void SceneUpdateContext::SetShapeTextureOrColor( SkScalar scale_x, SkScalar scale_y, const SkRect& paint_bounds, - std::vector paint_layers) { + std::vector paint_layers, + Layer* layer, + std::unique_ptr entity_node) { scenic::Image* image = GenerateImageIfNeeded( - color, scale_x, scale_y, paint_bounds, std::move(paint_layers)); + color, scale_x, scale_y, paint_bounds, std::move(paint_layers), layer, + std::move(entity_node)); if (image != nullptr) { scenic::Material material(session_); material.SetTexture(*image); @@ -146,7 +148,9 @@ scenic::Image* SceneUpdateContext::GenerateImageIfNeeded( SkScalar scale_x, SkScalar scale_y, const SkRect& paint_bounds, - std::vector paint_layers) { + std::vector paint_layers, + Layer* layer, + std::unique_ptr entity_node) { // Bail if there's nothing to paint. if (paint_layers.empty()) return nullptr; @@ -158,7 +162,13 @@ scenic::Image* SceneUpdateContext::GenerateImageIfNeeded( return nullptr; // Acquire a surface from the surface producer and register the paint tasks. - auto surface = surface_producer_->ProduceSurface(physical_size); + std::unique_ptr surface = + surface_producer_->ProduceSurface( + physical_size, + LayerRasterCacheKey( + // Root frame has a nullptr layer + layer ? layer->unique_id() : 0, Matrix()), + std::move(entity_node)); if (!surface) { FML_LOG(ERROR) << "Could not acquire a surface from the surface producer " @@ -180,7 +190,8 @@ scenic::Image* SceneUpdateContext::GenerateImageIfNeeded( return image; } -std::vector> +std::vector< + std::unique_ptr> SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) { TRACE_EVENT0("flutter", "SceneUpdateContext::ExecutePaintTasks"); std::vector> surfaces_to_submit; @@ -189,9 +200,10 @@ SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) { SkCanvas* canvas = task.surface->GetSkiaSurface()->getCanvas(); Layer::PaintContext context = {canvas, canvas, + frame.gr_context(), nullptr, - frame.context().frame_time(), - frame.context().engine_time(), + frame.context().raster_time(), + frame.context().ui_time(), frame.context().texture_registry(), &frame.context().raster_cache(), false}; @@ -210,11 +222,13 @@ SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) { } SceneUpdateContext::Entity::Entity(SceneUpdateContext& context) - : context_(context), - previous_entity_(context.top_entity_), - entity_node_(context.session()) { + : context_(context), previous_entity_(context.top_entity_) { + entity_node_ptr_ = std::make_unique(context.session()); + shape_node_ptr_ = std::make_unique(context.session()); + // TODO(SCN-1274): AddPart() and SetClip() will be deleted. + entity_node_ptr_->AddPart(*shape_node_ptr_); if (previous_entity_) - previous_entity_->entity_node_.AddChild(entity_node_); + previous_entity_->entity_node_ptr_->AddChild(*entity_node_ptr_); context.top_entity_ = this; } @@ -223,35 +237,19 @@ SceneUpdateContext::Entity::~Entity() { context_.top_entity_ = previous_entity_; } -SceneUpdateContext::Clip::Clip(SceneUpdateContext& context, - scenic::Shape& shape, - const SkRect& shape_bounds) - : Entity(context) { - scenic::ShapeNode shape_node(context.session()); - shape_node.SetShape(shape); - shape_node.SetTranslation(shape_bounds.width() * 0.5f + shape_bounds.left(), - shape_bounds.height() * 0.5f + shape_bounds.top(), - 0.f); - - entity_node().AddPart(shape_node); - entity_node().SetClip(0u, true /* clip to self */); -} - -SceneUpdateContext::Clip::~Clip() = default; - SceneUpdateContext::Transform::Transform(SceneUpdateContext& context, const SkMatrix& transform) : Entity(context), previous_scale_x_(context.top_scale_x_), previous_scale_y_(context.top_scale_y_) { if (!transform.isIdentity()) { - // TODO(MZ-192): The perspective and shear components in the matrix + // TODO(SCN-192): The perspective and shear components in the matrix // are not handled correctly. MatrixDecomposition decomposition(transform); if (decomposition.IsValid()) { entity_node().SetTranslation(decomposition.translation().x(), // decomposition.translation().y(), // - decomposition.translation().z() // + -decomposition.translation().z() // ); entity_node().SetScale(decomposition.scale().x(), // @@ -292,18 +290,29 @@ SceneUpdateContext::Transform::~Transform() { SceneUpdateContext::Frame::Frame(SceneUpdateContext& context, const SkRRect& rrect, SkColor color, - float elevation) + float local_elevation, + float world_elevation, + float depth, + Layer* layer) : Entity(context), rrect_(rrect), color_(color), - paint_bounds_(SkRect::MakeEmpty()) { - if (elevation != 0.0) - entity_node().SetTranslation(0.f, 0.f, elevation); + paint_bounds_(SkRect::MakeEmpty()), + layer_(layer) { + if (local_elevation != 0.0) { + if (depth > -1 && world_elevation >= depth) { + // TODO(mklim): Deal with bounds overflow correctly. + FML_LOG(ERROR) << "Elevation " << world_elevation << " is outside of " + << depth; + } + entity_node().SetTranslation(0.f, 0.f, -local_elevation); + } } SceneUpdateContext::Frame::~Frame() { - context().CreateFrame(entity_node(), rrect_, color_, paint_bounds_, - std::move(paint_layers_)); + context().CreateFrame(std::move(entity_node_ptr()), + std::move(shape_node_ptr()), rrect_, color_, + paint_bounds_, std::move(paint_layers_), layer_); } void SceneUpdateContext::Frame::AddPaintLayer(Layer* layer) { @@ -312,4 +321,17 @@ void SceneUpdateContext::Frame::AddPaintLayer(Layer* layer) { paint_bounds_.join(layer->paint_bounds()); } -} // namespace flow +SceneUpdateContext::Clip::Clip(SceneUpdateContext& context, + scenic::Shape& shape, + const SkRect& shape_bounds) + : Entity(context) { + shape_node().SetShape(shape); + shape_node().SetTranslation(shape_bounds.width() * 0.5f + shape_bounds.left(), + shape_bounds.height() * 0.5f + shape_bounds.top(), + 0.f); + entity_node().SetClip(0u, true /* clip to self */); + + SetEntityNodeClipPlanes(&entity_node(), shape_bounds); +} + +} // namespace flutter diff --git a/flow/scene_update_context.h b/flow/scene_update_context.h index 22e39e63ac195..ca66004735f32 100644 --- a/flow/scene_update_context.h +++ b/flow/scene_update_context.h @@ -10,7 +10,7 @@ #include #include "flutter/flow/compositor_context.h" -#include "flutter/fml/build_config.h" +#include "flutter/flow/raster_cache_key.h" #include "flutter/fml/compiler_specific.h" #include "flutter/fml/logging.h" #include "flutter/fml/macros.h" @@ -18,11 +18,9 @@ #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkSurface.h" -namespace flow { +namespace flutter { class Layer; -class ExportNodeHolder; -class ExportNode; class SceneUpdateContext { public: @@ -50,8 +48,19 @@ class SceneUpdateContext { public: virtual ~SurfaceProducer() = default; + // The produced surface owns the entity_node and has a layer_key for + // retained rendering. The surface will only be retained if the layer_key + // has a non-null layer pointer (layer_key.id()). virtual std::unique_ptr ProduceSurface( - const SkISize& size) = 0; + const SkISize& size, + const LayerRasterCacheKey& layer_key, + std::unique_ptr entity_node) = 0; + + // Query a retained entity node (owned by a retained surface) for retained + // rendering. + virtual bool HasRetainedNode(const LayerRasterCacheKey& key) const = 0; + virtual const scenic::EntityNode& GetRetainedNode( + const LayerRasterCacheKey& key) = 0; virtual void SubmitSurface( std::unique_ptr surface) = 0; @@ -63,21 +72,22 @@ class SceneUpdateContext { ~Entity(); SceneUpdateContext& context() { return context_; } - scenic::EntityNode& entity_node() { return entity_node_; } + scenic::EntityNode& entity_node() { return *entity_node_ptr_; } + std::unique_ptr& entity_node_ptr() { + return entity_node_ptr_; + } + + scenic::ShapeNode& shape_node() { return *shape_node_ptr_; } + std::unique_ptr& shape_node_ptr() { + return shape_node_ptr_; + } private: SceneUpdateContext& context_; Entity* const previous_entity_; - scenic::EntityNode entity_node_; - }; - - class Clip : public Entity { - public: - Clip(SceneUpdateContext& context, - scenic::Shape& shape, - const SkRect& shape_bounds); - ~Clip(); + std::unique_ptr entity_node_ptr_; + std::unique_ptr shape_node_ptr_; }; class Transform : public Entity { @@ -96,10 +106,17 @@ class SceneUpdateContext { class Frame : public Entity { public: + // When layer is not nullptr, the frame is associated with a layer subtree + // rooted with that layer. The frame may then create a surface that will be + // retained for that layer. Frame(SceneUpdateContext& context, const SkRRect& rrect, SkColor color, - float elevation); + float local_elevation = 0.0f, + float parent_elevation = 0.0f, + float depth = 0.0f, + Layer* layer = nullptr); + ~Frame(); void AddPaintLayer(Layer* layer); @@ -110,33 +127,31 @@ class SceneUpdateContext { std::vector paint_layers_; SkRect paint_bounds_; + Layer* layer_; + }; + + class Clip : public Entity { + public: + Clip(SceneUpdateContext& context, + scenic::Shape& shape, + const SkRect& shape_bounds); + ~Clip() = default; }; SceneUpdateContext(scenic::Session* session, SurfaceProducer* surface_producer); - - ~SceneUpdateContext(); + ~SceneUpdateContext() = default; scenic::Session* session() { return session_; } + Entity* top_entity() { return top_entity_; } + bool has_metrics() const { return !!metrics_; } void set_metrics(fuchsia::ui::gfx::MetricsPtr metrics) { metrics_ = std::move(metrics); } const fuchsia::ui::gfx::MetricsPtr& metrics() const { return metrics_; } - void AddChildScene(ExportNode* export_node, - SkPoint offset, - bool hit_testable); - - // Adds reference to |export_node| so we can call export_node->Dispose() in - // our destructor. Caller is responsible for calling RemoveExportNode() before - // |export_node| is destroyed. - void AddExportNode(ExportNode* export_node); - - // Removes reference to |export_node|. - void RemoveExportNode(ExportNode* export_node); - // TODO(chinmaygarde): This method must submit the surfaces as soon as paint // tasks are done. However, given that there is no support currently for // Vulkan semaphores, we need to submit all the surfaces after an explicit @@ -147,6 +162,20 @@ class SceneUpdateContext { std::vector> ExecutePaintTasks( CompositorContext::ScopedFrame& frame); + float ScaleX() const { return metrics_->scale_x * top_scale_x_; } + float ScaleY() const { return metrics_->scale_y * top_scale_y_; } + + // The transformation matrix of the current context. It's used to construct + // the LayerRasterCacheKey for a given layer. + SkMatrix Matrix() const { return SkMatrix::MakeScale(ScaleX(), ScaleY()); } + + bool HasRetainedNode(const LayerRasterCacheKey& key) const { + return surface_producer_->HasRetainedNode(key); + } + const scenic::EntityNode& GetRetainedNode(const LayerRasterCacheKey& key) { + return surface_producer_->GetRetainedNode(key); + } + private: struct PaintTask { std::unique_ptr surface; @@ -158,23 +187,36 @@ class SceneUpdateContext { std::vector layers; }; - void CreateFrame(scenic::EntityNode& entity_node, + // Setup the entity_node as a frame that materialize all the paint_layers. In + // most cases, this creates a VulkanSurface (SurfaceProducerSurface) by + // calling SetShapeTextureOrColor and GenerageImageIfNeeded. Such surface will + // own the associated entity_node. If the layer pointer isn't nullptr, the + // surface (and thus the entity_node) will be retained for that layer to + // improve the performance. + void CreateFrame(std::unique_ptr entity_node, + std::unique_ptr shape_node, const SkRRect& rrect, SkColor color, const SkRect& paint_bounds, - std::vector paint_layers); + std::vector paint_layers, + Layer* layer); void SetShapeTextureOrColor(scenic::ShapeNode& shape_node, SkColor color, SkScalar scale_x, SkScalar scale_y, const SkRect& paint_bounds, - std::vector paint_layers); + std::vector paint_layers, + Layer* layer, + std::unique_ptr entity_node); void SetShapeColor(scenic::ShapeNode& shape_node, SkColor color); - scenic::Image* GenerateImageIfNeeded(SkColor color, - SkScalar scale_x, - SkScalar scale_y, - const SkRect& paint_bounds, - std::vector paint_layers); + scenic::Image* GenerateImageIfNeeded( + SkColor color, + SkScalar scale_x, + SkScalar scale_y, + const SkRect& paint_bounds, + std::vector paint_layers, + Layer* layer, + std::unique_ptr entity_node); Entity* top_entity_ = nullptr; float top_scale_x_ = 1.f; @@ -187,12 +229,9 @@ class SceneUpdateContext { std::vector paint_tasks_; - // Save ExportNodes so we can dispose them in our destructor. - std::set export_nodes_; - FML_DISALLOW_COPY_AND_ASSIGN(SceneUpdateContext); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_SCENE_UPDATE_CONTEXT_H_ diff --git a/flow/skia_gpu_object.cc b/flow/skia_gpu_object.cc index 1f789212e6ba9..bf1b0a1d2a779 100644 --- a/flow/skia_gpu_object.cc +++ b/flow/skia_gpu_object.cc @@ -6,7 +6,7 @@ #include "flutter/fml/message_loop.h" -namespace flow { +namespace flutter { SkiaUnrefQueue::SkiaUnrefQueue(fml::RefPtr task_runner, fml::TimeDelta delay) @@ -41,4 +41,4 @@ void SkiaUnrefQueue::Drain() { } } -} // namespace flow +} // namespace flutter diff --git a/flow/skia_gpu_object.h b/flow/skia_gpu_object.h index c7d814bfcb5fc..4c079af96ee95 100644 --- a/flow/skia_gpu_object.h +++ b/flow/skia_gpu_object.h @@ -13,7 +13,7 @@ #include "flutter/fml/task_runner.h" #include "third_party/skia/include/core/SkRefCnt.h" -namespace flow { +namespace flutter { // A queue that holds Skia objects that must be destructed on the the given task // runner. @@ -83,6 +83,6 @@ class SkiaGPUObject { FML_DISALLOW_COPY_AND_ASSIGN(SkiaGPUObject); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_SKIA_GPU_OBJECT_H_ diff --git a/flow/texture.cc b/flow/texture.cc index bef0de01b1cbd..7bc40f0c1d43b 100644 --- a/flow/texture.cc +++ b/flow/texture.cc @@ -4,7 +4,7 @@ #include "flutter/flow/texture.h" -namespace flow { +namespace flutter { TextureRegistry::TextureRegistry() = default; @@ -39,4 +39,4 @@ Texture::Texture(int64_t id) : id_(id) {} Texture::~Texture() = default; -} // namespace flow +} // namespace flutter diff --git a/flow/texture.h b/flow/texture.h index 414a11dc820e8..749e3835b236a 100644 --- a/flow/texture.h +++ b/flow/texture.h @@ -11,7 +11,7 @@ #include "flutter/fml/synchronization/waitable_event.h" #include "third_party/skia/include/core/SkCanvas.h" -namespace flow { +namespace flutter { class Texture { protected: @@ -22,7 +22,10 @@ class Texture { virtual ~Texture(); // Called from GPU thread. - virtual void Paint(SkCanvas& canvas, const SkRect& bounds, bool freeze) = 0; + virtual void Paint(SkCanvas& canvas, + const SkRect& bounds, + bool freeze, + GrContext* context) = 0; // Called from GPU thread. virtual void OnGrContextCreated() = 0; @@ -67,6 +70,6 @@ class TextureRegistry { FML_DISALLOW_COPY_AND_ASSIGN(TextureRegistry); }; -} // namespace flow +} // namespace flutter #endif // FLUTTER_FLOW_TEXTURE_H_ diff --git a/flow/view_holder.cc b/flow/view_holder.cc new file mode 100644 index 0000000000000..2baba58f67f60 --- /dev/null +++ b/flow/view_holder.cc @@ -0,0 +1,146 @@ +// 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. + +#include "flutter/flow/view_holder.h" + +#include "flutter/fml/thread_local.h" + +namespace { + +using ViewHolderBindings = + std::unordered_map>; + +FML_THREAD_LOCAL fml::ThreadLocalUniquePtr + tls_view_holder_bindings; + +fuchsia::ui::gfx::ViewProperties ToViewProperties(float width, + float height, + float insetTop, + float insetRight, + float insetBottom, + float insetLeft, + bool focusable) { + return fuchsia::ui::gfx::ViewProperties({ + .bounding_box = fuchsia::ui::gfx::BoundingBox({ + .min = fuchsia::ui::gfx::vec3({ + .x = 0.f, + .y = 0.f, + .z = -1000.f, + }), + .max = fuchsia::ui::gfx::vec3({.x = width, .y = height, .z = 0.f}), + }), + .inset_from_min = fuchsia::ui::gfx::vec3({ + .x = insetLeft, + .y = insetTop, + .z = 0.f, + }), + .inset_from_max = fuchsia::ui::gfx::vec3({ + .x = insetRight, + .y = insetBottom, + .z = 0.f, + }), + .focus_change = focusable, + }); +} + +} // namespace + +namespace flutter { + +ViewHolder::ViewHolder(fml::RefPtr ui_task_runner, + fuchsia::ui::views::ViewHolderToken view_holder_token, + BindCallback on_bind_callback) + : pending_view_holder_token_(std::move(view_holder_token)), + ui_task_runner_(std::move(ui_task_runner)), + pending_bind_callback_(std::move(on_bind_callback)) { + FML_DCHECK(pending_view_holder_token_.value); + FML_DCHECK(ui_task_runner_); +} + +void ViewHolder::Create(zx_koid_t id, + fml::RefPtr ui_task_runner, + fuchsia::ui::views::ViewHolderToken view_holder_token, + BindCallback on_bind_callback) { + // This GPU thread contains at least 1 ViewHolder. Initialize the per-thread + // bindings. + if (tls_view_holder_bindings.get() == nullptr) { + tls_view_holder_bindings.reset(new ViewHolderBindings()); + } + + auto* bindings = tls_view_holder_bindings.get(); + FML_DCHECK(bindings); + FML_DCHECK(bindings->find(id) == bindings->end()); + + auto view_holder = std::unique_ptr( + new ViewHolder(std::move(ui_task_runner), std::move(view_holder_token), + std::move(on_bind_callback))); + bindings->emplace(id, std::move(view_holder)); +} + +void ViewHolder::Destroy(zx_koid_t id) { + auto* bindings = tls_view_holder_bindings.get(); + FML_DCHECK(bindings); + + bindings->erase(id); +} + +ViewHolder* ViewHolder::FromId(zx_koid_t id) { + auto* bindings = tls_view_holder_bindings.get(); + if (!bindings) { + return nullptr; + } + + auto binding = bindings->find(id); + if (binding == bindings->end()) { + return nullptr; + } + + return binding->second.get(); +} + +void ViewHolder::UpdateScene(SceneUpdateContext& context, + const SkPoint& offset, + const SkSize& size, + bool hit_testable) { + if (pending_view_holder_token_.value) { + entity_node_ = std::make_unique(context.session()); + view_holder_ = std::make_unique( + context.session(), std::move(pending_view_holder_token_), + "Flutter SceneHost"); + + entity_node_->Attach(*view_holder_); + ui_task_runner_->PostTask( + [bind_callback = std::move(pending_bind_callback_), + view_holder_id = view_holder_->id()]() { + bind_callback(view_holder_id); + }); + } + FML_DCHECK(entity_node_); + FML_DCHECK(view_holder_); + + context.top_entity()->entity_node().AddChild(*entity_node_); + entity_node_->SetTranslation(offset.x(), offset.y(), -0.1f); + entity_node_->SetHitTestBehavior( + hit_testable ? fuchsia::ui::gfx::HitTestBehavior::kDefault + : fuchsia::ui::gfx::HitTestBehavior::kSuppress); + if (has_pending_properties_) { + view_holder_->SetViewProperties(std::move(pending_properties_)); + + has_pending_properties_ = false; + } +} + +void ViewHolder::SetProperties(double width, + double height, + double insetTop, + double insetRight, + double insetBottom, + double insetLeft, + bool focusable) { + pending_properties_ = ToViewProperties(width, height, insetTop, insetRight, + insetBottom, insetLeft, focusable); + has_pending_properties_ = true; +} + +} // namespace flutter diff --git a/flow/view_holder.h b/flow/view_holder.h new file mode 100644 index 0000000000000..2f0e216c47b77 --- /dev/null +++ b/flow/view_holder.h @@ -0,0 +1,75 @@ +// 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. + +#ifndef FLUTTER_FLOW_VIEW_HOLDER_H_ +#define FLUTTER_FLOW_VIEW_HOLDER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "flutter/flow/scene_update_context.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/ref_counted.h" +#include "flutter/fml/task_runner.h" + +namespace flutter { + +// Represents a Scenic |ViewHolder| resource that imports a |View| from another +// session. +// +// This object is created and destroyed on the |Rasterizer|'s thread. +class ViewHolder { + public: + using BindCallback = std::function; + + static void Create(zx_koid_t id, + fml::RefPtr ui_task_runner, + fuchsia::ui::views::ViewHolderToken view_holder_token, + BindCallback on_bind_callback); + static void Destroy(zx_koid_t id); + static ViewHolder* FromId(zx_koid_t id); + + // Sets the properties of the child view by issuing a Scenic command. + void SetProperties(double width, + double height, + double insetTop, + double insetRight, + double insetBottom, + double insetLeft, + bool focusable); + + // Creates or updates the contained ViewHolder resource using the specified + // |SceneUpdateContext|. + void UpdateScene(SceneUpdateContext& context, + const SkPoint& offset, + const SkSize& size, + bool hit_testable); + + private: + ViewHolder(fml::RefPtr ui_task_runner, + fuchsia::ui::views::ViewHolderToken view_holder_token, + BindCallback on_bind_callback); + + fuchsia::ui::gfx::ViewProperties pending_properties_; + fuchsia::ui::views::ViewHolderToken pending_view_holder_token_; + fml::RefPtr ui_task_runner_; + std::unique_ptr entity_node_; + std::unique_ptr view_holder_; + BindCallback pending_bind_callback_; + bool has_pending_properties_ = false; + + FML_DISALLOW_COPY_AND_ASSIGN(ViewHolder); +}; + +} // namespace flutter + +#endif // FLUTTER_FLOW_VIEW_HOLDER_H_ diff --git a/flutter_kernel_transformers/BUILD.gn b/flutter_kernel_transformers/BUILD.gn index 0411b4b9976c2..bde059f34990f 100644 --- a/flutter_kernel_transformers/BUILD.gn +++ b/flutter_kernel_transformers/BUILD.gn @@ -15,9 +15,9 @@ dart_library("flutter_kernel_transformers") { ] deps = [ + "//third_party/dart-pkg/pub/meta", "//third_party/dart/pkg/front_end", "//third_party/dart/pkg/kernel", "//third_party/dart/pkg/vm", - "//third_party/dart-pkg/pub/meta", ] } diff --git a/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart b/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart index 47fa4f341f826..a4abc5b3eb534 100644 --- a/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart +++ b/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart @@ -76,7 +76,7 @@ void _maybeAddCreationLocationArgument( } final NamedExpression namedArgument = - new NamedExpression(_creationLocationParameterName, creationLocation); + NamedExpression(_creationLocationParameterName, creationLocation); namedArgument.parent = arguments; arguments.named.add(namedArgument); } @@ -144,31 +144,31 @@ class _WidgetCallSiteTransformer extends Transformer { /// locations of the parameters passed in from the source location of the /// constructor call but it is convenient to bundle the location and names /// of the parameters passed in so that tools can show parameter locations - /// without reparsing the source code. + /// without re-parsing the source code. ConstructorInvocation _constructLocation( Location location, { String name, ListLiteral parameterLocations, - bool showFile: true, + bool showFile = true, }) { final List arguments = [ - new NamedExpression('line', new IntLiteral(location.line)), - new NamedExpression('column', new IntLiteral(location.column)), + NamedExpression('line', IntLiteral(location.line)), + NamedExpression('column', IntLiteral(location.column)), ]; if (showFile) { - arguments.add(new NamedExpression( - 'file', new StringLiteral(location.file.toString()))); + arguments.add(NamedExpression( + 'file', StringLiteral(location.file.toString()))); } if (name != null) { - arguments.add(new NamedExpression('name', new StringLiteral(name))); + arguments.add(NamedExpression('name', StringLiteral(name))); } if (parameterLocations != null) { arguments - .add(new NamedExpression('parameterLocations', parameterLocations)); + .add(NamedExpression('parameterLocations', parameterLocations)); } - return new ConstructorInvocation( + return ConstructorInvocation( _locationClass.constructors.first, - new Arguments([], named: arguments), + Arguments([], named: arguments), isConst: true, ); } @@ -243,7 +243,7 @@ class _WidgetCallSiteTransformer extends Transformer { _creationLocationParameterName, ); if (creationLocationParameter != null) { - return new VariableGet(creationLocationParameter); + return VariableGet(creationLocationParameter); } } @@ -270,7 +270,7 @@ class _WidgetCallSiteTransformer extends Transformer { } return _constructLocation( location, - parameterLocations: new ListLiteral( + parameterLocations: ListLiteral( parameterLocations, typeArgument: _locationClass.thisType, isConst: true, @@ -342,12 +342,12 @@ class WidgetCreatorTracker implements ProgramTransformer { return; } clazz.implementedTypes - .add(new Supertype(_hasCreationLocationClass, [])); + .add(Supertype(_hasCreationLocationClass, [])); // We intentionally use the library context of the _HasCreationLocation // class for the private field even if [clazz] is in a different library // so that all classes implementing Widget behave consistently. - final Field locationField = new Field( - new Name( + final Field locationField = Field( + Name( _locationFieldName, _hasCreationLocationClass.enclosingLibrary, ), @@ -356,7 +356,7 @@ class WidgetCreatorTracker implements ProgramTransformer { clazz.addMember(locationField); final Set _handledConstructors = - new Set.identity(); + Set.identity(); void handleConstructor(Constructor constructor) { if (!_handledConstructors.add(constructor)) { @@ -366,7 +366,7 @@ class WidgetCreatorTracker implements ProgramTransformer { constructor.function, _creationLocationParameterName, )); - final VariableDeclaration variable = new VariableDeclaration( + final VariableDeclaration variable = VariableDeclaration( _creationLocationParameterName, type: _locationClass.thisType, ); @@ -386,7 +386,7 @@ class WidgetCreatorTracker implements ProgramTransformer { _maybeAddCreationLocationArgument( initializer.arguments, initializer.target.function, - new VariableGet(variable), + VariableGet(variable), _locationClass, ); hasRedirectingInitializer = true; @@ -394,20 +394,20 @@ class WidgetCreatorTracker implements ProgramTransformer { } } if (!hasRedirectingInitializer) { - constructor.initializers.add(new FieldInitializer( + constructor.initializers.add(FieldInitializer( locationField, - new VariableGet(variable), + VariableGet(variable), )); // TODO(jacobr): add an assert verifying the locationField is not - // null. Curently we cannot safely add this assert because we do not + // null. Currently, we cannot safely add this assert because we do not // handle Widget classes with optional positional arguments. There are // no Widget classes in the flutter repo with optional positional // arguments but it is possible users could add classes with optional // positional arguments. // - // constructor.initializers.add(new AssertInitializer(new AssertStatement( - // new IsExpression( - // new VariableGet(variable), _locationClass.thisType), + // constructor.initializers.add(AssertInitializer(AssertStatement( + // IsExpression( + // VariableGet(variable), _locationClass.thisType), // conditionStartOffset: constructor.fileOffset, // conditionEndOffset: constructor.fileOffset, // ))); @@ -419,7 +419,7 @@ class WidgetCreatorTracker implements ProgramTransformer { } Component _computeFullProgram(Component deltaProgram) { - final Set libraries = new Set(); + final Set libraries = {}; final List workList = []; for (Library library in deltaProgram.libraries) { if (libraries.add(library)) { @@ -434,7 +434,7 @@ class WidgetCreatorTracker implements ProgramTransformer { } } } - return new Component()..libraries.addAll(libraries); + return Component()..libraries.addAll(libraries); } /// Transform the given [program]. @@ -459,13 +459,13 @@ class WidgetCreatorTracker implements ProgramTransformer { // TODO(jacobr): once there is a working incremental ClassHierarchy // constructor switch to using it instead of building a ClassHierarchy off // the full program. - hierarchy = new ClassHierarchy( + hierarchy = ClassHierarchy( _computeFullProgram(program), onAmbiguousSupertypes: (Class cls, Supertype a, Supertype b) { }, ); - final Set transformedClasses = new Set.identity(); - final Set librariesToTransform = new Set.identity() + final Set transformedClasses = Set.identity(); + final Set librariesToTransform = Set.identity() ..addAll(libraries); for (Library library in libraries) { @@ -483,7 +483,7 @@ class WidgetCreatorTracker implements ProgramTransformer { // Transform call sites to pass the location parameter. final _WidgetCallSiteTransformer callsiteTransformer = - new _WidgetCallSiteTransformer( + _WidgetCallSiteTransformer( hierarchy, widgetClass: _widgetClass, locationClass: _locationClass, @@ -528,7 +528,7 @@ class WidgetCreatorTracker implements ProgramTransformer { if (procedure.isFactory) { _maybeAddNamedParameter( procedure.function, - new VariableDeclaration( + VariableDeclaration( _creationLocationParameterName, type: _locationClass.thisType, ), @@ -544,14 +544,14 @@ class WidgetCreatorTracker implements ProgramTransformer { } final Set _handledConstructors = - new Set.identity(); + Set.identity(); void handleConstructor(Constructor constructor) { if (!_handledConstructors.add(constructor)) { return; } - final VariableDeclaration variable = new VariableDeclaration( + final VariableDeclaration variable = VariableDeclaration( _creationLocationParameterName, type: _locationClass.thisType, ); @@ -575,7 +575,7 @@ class WidgetCreatorTracker implements ProgramTransformer { _maybeAddCreationLocationArgument( initializer.arguments, initializer.target.function, - new VariableGet(variable), + VariableGet(variable), _locationClass, ); } else if (initializer is SuperInitializer && @@ -583,7 +583,7 @@ class WidgetCreatorTracker implements ProgramTransformer { _maybeAddCreationLocationArgument( initializer.arguments, initializer.target.function, - new VariableGet(variable), + VariableGet(variable), _locationClass, ); } diff --git a/fml/BUILD.gn b/fml/BUILD.gn index 3a7d76df80762..26f51d99c9c87 100644 --- a/fml/BUILD.gn +++ b/fml/BUILD.gn @@ -2,9 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/fuchsia/sdk.gni") + source_set("fml") { sources = [ - "arraysize.h", "base32.cc", "base32.h", "build_config.h", @@ -12,8 +13,9 @@ source_set("fml") { "command_line.cc", "command_line.h", "compiler_specific.h", + "concurrent_message_loop.cc", + "concurrent_message_loop.h", "eintr_wrapper.h", - "export.h", "file.cc", "file.h", "icu_util.cc", @@ -44,14 +46,16 @@ source_set("fml") { "native_library.h", "paths.cc", "paths.h", + "size.h", "string_view.cc", "string_view.h", "synchronization/atomic_object.h", "synchronization/count_down_latch.cc", "synchronization/count_down_latch.h", + "synchronization/semaphore.cc", + "synchronization/semaphore.h", "synchronization/shared_mutex.h", "synchronization/thread_annotations.h", - "synchronization/thread_checker.h", "synchronization/waitable_event.cc", "synchronization/waitable_event.h", "task_runner.cc", @@ -81,7 +85,10 @@ source_set("fml") { configs += [ "//third_party/icu:icu_config" ] - public_configs = [ "$flutter_root:config" ] + public_configs = [ + "$flutter_root:config", + "$flutter_root/common:flutter_config", + ] libs = [] @@ -104,6 +111,8 @@ source_set("fml") { "platform/darwin/scoped_block.mm", "platform/darwin/scoped_nsobject.h", "platform/darwin/scoped_nsobject.mm", + "platform/darwin/string_range_sanitization.h", + "platform/darwin/string_range_sanitization.mm", ] libs += [ "Foundation.framework" ] @@ -127,13 +136,10 @@ source_set("fml") { } if (is_android) { - # Don't filter away these Linux sources on Android. - set_sources_assignment_filter([]) sources += [ "platform/linux/timerfd.cc", "platform/linux/timerfd.h", ] - set_sources_assignment_filter(sources_assignment_filter) } if (is_linux) { @@ -149,7 +155,9 @@ source_set("fml") { if (is_fuchsia) { sources += [ "platform/fuchsia/paths_fuchsia.cc" ] - public_deps += [ "//zircon/public/lib/trace" ] + if (!using_fuchsia_sdk) { + public_deps += [ "//zircon/public/lib/trace" ] + } } if (is_win) { @@ -186,10 +194,11 @@ executable("fml_unittests") { "message_loop_unittests.cc", "message_unittests.cc", "paths_unittests.cc", + "platform/darwin/string_range_sanitization_unittests.mm", "string_view_unittest.cc", "synchronization/count_down_latch_unittests.cc", + "synchronization/semaphore_unittest.cc", "synchronization/thread_annotations_unittest.cc", - "synchronization/thread_checker_unittest.cc", "synchronization/waitable_event_unittest.cc", "thread_local_unittests.cc", "thread_unittests.cc", diff --git a/fml/arraysize.h b/fml/arraysize.h deleted file mode 100644 index 636939812bed7..0000000000000 --- a/fml/arraysize.h +++ /dev/null @@ -1,16 +0,0 @@ -// 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. - -#ifndef FLUTTER_FML_ARRAYSIZE_H_ -#define FLUTTER_FML_ARRAYSIZE_H_ - -#include - -#ifndef arraysize -template -char (&ArraySizeHelper(T (&array)[N]))[N]; -#define arraysize(array) (sizeof(ArraySizeHelper(array))) -#endif - -#endif // FLUTTER_FML_ARRAYSIZE_H_ diff --git a/fml/command_line.h b/fml/command_line.h index e1d06e6e6bed5..ea25151641ddd 100644 --- a/fml/command_line.h +++ b/fml/command_line.h @@ -33,8 +33,8 @@ // mostly explains a.), c. it makes parsing "subcommands", like "my_program // --flag_for_my_program subcommand --flag_for_subcommand" saner. -#ifndef LIB_FXL_COMMAND_LINE_H_ -#define LIB_FXL_COMMAND_LINE_H_ +#ifndef LIB_FML_COMMAND_LINE_H_ +#define LIB_FML_COMMAND_LINE_H_ #include @@ -239,4 +239,4 @@ std::vector CommandLineToArgv(const CommandLine& command_line); } // namespace fml -#endif // LIB_FXL_COMMAND_LINE_H_ +#endif // LIB_FML_COMMAND_LINE_H_ diff --git a/fml/command_line_unittest.cc b/fml/command_line_unittest.cc index c04619e483e28..31907a0fb4b07 100644 --- a/fml/command_line_unittest.cc +++ b/fml/command_line_unittest.cc @@ -6,8 +6,8 @@ #include -#include "flutter/fml/arraysize.h" #include "flutter/fml/macros.h" +#include "flutter/fml/size.h" #include "gtest/gtest.h" namespace fml { @@ -197,7 +197,7 @@ TEST(CommandLineTest, CommmandLineFromIterators) { { static const char* const argv[] = {"my_program", "--flag=value", "arg"}; - auto cl = CommandLineFromIterators(argv, argv + arraysize(argv)); + auto cl = CommandLineFromIterators(argv, argv + fml::size(argv)); EXPECT_TRUE(cl.has_argv0()); EXPECT_EQ(argv[0], cl.argv0()); std::vector expected_options = { @@ -211,7 +211,7 @@ TEST(CommandLineTest, CommmandLineFromIterators) { TEST(CommandLineTest, CommandLineFromArgcArgv) { static const char* const argv[] = {"my_program", "--flag=value", "arg"}; - const int argc = static_cast(arraysize(argv)); + const int argc = static_cast(fml::size(argv)); auto cl = CommandLineFromArgcArgv(argc, argv); EXPECT_TRUE(cl.has_argv0()); diff --git a/fml/concurrent_message_loop.cc b/fml/concurrent_message_loop.cc new file mode 100644 index 0000000000000..23c820787faf9 --- /dev/null +++ b/fml/concurrent_message_loop.cc @@ -0,0 +1,70 @@ +// 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. + +#include "flutter/fml/concurrent_message_loop.h" + +#include + +#include "flutter/fml/thread.h" +#include "flutter/fml/trace_event.h" + +namespace fml { + +ConcurrentMessageLoop::ConcurrentMessageLoop() + : worker_count_(std::max(std::thread::hardware_concurrency(), 1u)), + shutdown_latch_(worker_count_), + shutdown_(false) { + for (size_t i = 0; i < worker_count_; ++i) { + workers_.emplace_back([i, this]() { + fml::Thread::SetCurrentThreadName( + std::string{"io.flutter.worker." + std::to_string(i + 1)}); + WorkerMain(); + }); + } +} + +ConcurrentMessageLoop::~ConcurrentMessageLoop() { + Terminate(); + shutdown_latch_.Wait(); + for (auto& worker : workers_) { + worker.join(); + } +} + +// |fml::MessageLoopImpl| +void ConcurrentMessageLoop::Run() { + FML_CHECK(false); +} + +// |fml::MessageLoopImpl| +void ConcurrentMessageLoop::Terminate() { + std::lock_guard lock(wait_condition_mutex_); + shutdown_ = true; + wait_condition_.notify_all(); +} + +// |fml::MessageLoopImpl| +void ConcurrentMessageLoop::WakeUp(fml::TimePoint time_point) { + // Assume that the clocks are not the same. + const auto duration = std::chrono::nanoseconds( + (time_point - fml::TimePoint::Now()).ToNanoseconds()); + next_wake_ = std::chrono::high_resolution_clock::now() + duration; + wait_condition_.notify_all(); +} + +void ConcurrentMessageLoop::WorkerMain() { + while (!shutdown_) { + std::unique_lock lock(wait_condition_mutex_); + if (!shutdown_) { + wait_condition_.wait(lock); + } + TRACE_EVENT0("fml", "ConcurrentWorkerWake"); + RunSingleExpiredTaskNow(); + } + + RunExpiredTasksNow(); + shutdown_latch_.CountDown(); +} + +} // namespace fml diff --git a/fml/concurrent_message_loop.h b/fml/concurrent_message_loop.h new file mode 100644 index 0000000000000..7879d05239f83 --- /dev/null +++ b/fml/concurrent_message_loop.h @@ -0,0 +1,55 @@ +// 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. + +#ifndef FLUTTER_FML_CONCURRENT_MESSAGE_LOOP_H_ +#define FLUTTER_FML_CONCURRENT_MESSAGE_LOOP_H_ + +#include +#include +#include +#include +#include + +#include "flutter/fml/macros.h" +#include "flutter/fml/message_loop_impl.h" +#include "flutter/fml/synchronization/count_down_latch.h" +#include "flutter/fml/synchronization/thread_annotations.h" + +namespace fml { + +class ConcurrentMessageLoop : public MessageLoopImpl { + private: + const size_t worker_count_; + std::mutex wait_condition_mutex_; + std::condition_variable wait_condition_; + std::vector workers_; + CountDownLatch shutdown_latch_; + std::chrono::high_resolution_clock::time_point next_wake_; + std::atomic_bool shutdown_; + + ConcurrentMessageLoop(); + + ~ConcurrentMessageLoop(); + + // |fml::MessageLoopImpl| + void Run() override; + + // |fml::MessageLoopImpl| + void Terminate() override; + + // |fml::MessageLoopImpl| + void WakeUp(fml::TimePoint time_point) override; + + static void WorkerMain(ConcurrentMessageLoop* loop); + + void WorkerMain(); + + FML_FRIEND_MAKE_REF_COUNTED(ConcurrentMessageLoop); + FML_FRIEND_REF_COUNTED_THREAD_SAFE(ConcurrentMessageLoop); + FML_DISALLOW_COPY_AND_ASSIGN(ConcurrentMessageLoop); +}; + +} // namespace fml + +#endif // FLUTTER_FML_CONCURRENT_MESSAGE_LOOP_H_ diff --git a/fml/export.h b/fml/export.h deleted file mode 100644 index ea9bf883f9ac3..0000000000000 --- a/fml/export.h +++ /dev/null @@ -1,16 +0,0 @@ -// 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. - -#ifndef FLUTTER_FML_EXPORT_H_ -#define FLUTTER_FML_EXPORT_H_ - -#include "flutter/fml/build_config.h" - -#if OS_WIN -#define FML_EXPORT __declspec(dllimport) -#else -#define FML_EXPORT __attribute__((visibility("default"))) -#endif - -#endif // FLUTTER_FML_EXPORT_H_ diff --git a/fml/mapping.cc b/fml/mapping.cc index 11882b6662bbf..7ffacfb493890 100644 --- a/fml/mapping.cc +++ b/fml/mapping.cc @@ -4,12 +4,67 @@ #include "flutter/fml/mapping.h" +#include + namespace fml { +// FileMapping + uint8_t* FileMapping::GetMutableMapping() { return mutable_mapping_; } +std::unique_ptr FileMapping::CreateReadOnly( + const std::string& path) { + return CreateReadOnly(OpenFile(path.c_str(), false, FilePermission::kRead), + ""); +} + +std::unique_ptr FileMapping::CreateReadOnly( + const fml::UniqueFD& base_fd, + const std::string& sub_path) { + if (sub_path.size() != 0) { + return CreateReadOnly( + OpenFile(base_fd, sub_path.c_str(), false, FilePermission::kRead), ""); + } + + auto mapping = std::make_unique( + base_fd, std::initializer_list{Protection::kRead}); + + if (mapping->GetSize() == 0 || mapping->GetMapping() == nullptr) { + return nullptr; + } + + return mapping; +} + +std::unique_ptr FileMapping::CreateReadExecute( + const std::string& path) { + return CreateReadExecute( + OpenFile(path.c_str(), false, FilePermission::kRead)); +} + +std::unique_ptr FileMapping::CreateReadExecute( + const fml::UniqueFD& base_fd, + const std::string& sub_path) { + if (sub_path.size() != 0) { + return CreateReadExecute( + OpenFile(base_fd, sub_path.c_str(), false, FilePermission::kRead), ""); + } + + auto mapping = std::make_unique( + base_fd, std::initializer_list{Protection::kRead, + Protection::kExecute}); + + if (mapping->GetSize() == 0 || mapping->GetMapping() == nullptr) { + return nullptr; + } + + return mapping; +} + +// Data Mapping + DataMapping::DataMapping(std::vector data) : data_(std::move(data)) {} DataMapping::~DataMapping() = default; @@ -22,6 +77,8 @@ const uint8_t* DataMapping::GetMapping() const { return data_.data(); } +// NonOwnedMapping + size_t NonOwnedMapping::GetSize() const { return size_; } @@ -30,4 +87,37 @@ const uint8_t* NonOwnedMapping::GetMapping() const { return data_; } +// Symbol Mapping + +SymbolMapping::SymbolMapping(fml::RefPtr native_library, + const char* symbol_name) + : native_library_(std::move(native_library)) { + if (native_library_ && symbol_name != nullptr) { + mapping_ = native_library_->ResolveSymbol(symbol_name); + + if (mapping_ == nullptr) { + // Apparently, dart_bootstrap seems to account for the Mac behavior of + // requiring the underscore prefixed symbol name on non-Mac platforms as + // well. As a fallback, check the underscore prefixed variant of the + // symbol name and allow callers to not have handle this on a per platform + // toolchain quirk basis. + + std::stringstream underscore_symbol_name; + underscore_symbol_name << "_" << symbol_name; + mapping_ = + native_library_->ResolveSymbol(underscore_symbol_name.str().c_str()); + } + } +} + +SymbolMapping::~SymbolMapping() = default; + +size_t SymbolMapping::GetSize() const { + return 0; +} + +const uint8_t* SymbolMapping::GetMapping() const { + return mapping_; +} + } // namespace fml diff --git a/fml/mapping.h b/fml/mapping.h index 05894a5c219a4..90b88cc15840c 100644 --- a/fml/mapping.h +++ b/fml/mapping.h @@ -13,6 +13,7 @@ #include "flutter/fml/build_config.h" #include "flutter/fml/file.h" #include "flutter/fml/macros.h" +#include "flutter/fml/native_library.h" #include "flutter/fml/unique_fd.h" namespace fml { @@ -31,7 +32,7 @@ class Mapping { FML_DISALLOW_COPY_AND_ASSIGN(Mapping); }; -class FileMapping : public Mapping { +class FileMapping final : public Mapping { public: enum class Protection { kRead, @@ -45,8 +46,23 @@ class FileMapping : public Mapping { ~FileMapping() override; + static std::unique_ptr CreateReadOnly(const std::string& path); + + static std::unique_ptr CreateReadOnly( + const fml::UniqueFD& base_fd, + const std::string& sub_path = ""); + + static std::unique_ptr CreateReadExecute( + const std::string& path); + + static std::unique_ptr CreateReadExecute( + const fml::UniqueFD& base_fd, + const std::string& sub_path = ""); + + // |Mapping| size_t GetSize() const override; + // |Mapping| const uint8_t* GetMapping() const override; uint8_t* GetMutableMapping(); @@ -63,14 +79,16 @@ class FileMapping : public Mapping { FML_DISALLOW_COPY_AND_ASSIGN(FileMapping); }; -class DataMapping : public Mapping { +class DataMapping final : public Mapping { public: DataMapping(std::vector data); ~DataMapping() override; + // |Mapping| size_t GetSize() const override; + // |Mapping| const uint8_t* GetMapping() const override; private: @@ -79,13 +97,15 @@ class DataMapping : public Mapping { FML_DISALLOW_COPY_AND_ASSIGN(DataMapping); }; -class NonOwnedMapping : public Mapping { +class NonOwnedMapping final : public Mapping { public: NonOwnedMapping(const uint8_t* data, size_t size) : data_(data), size_(size) {} + // |Mapping| size_t GetSize() const override; + // |Mapping| const uint8_t* GetMapping() const override; private: @@ -95,6 +115,26 @@ class NonOwnedMapping : public Mapping { FML_DISALLOW_COPY_AND_ASSIGN(NonOwnedMapping); }; +class SymbolMapping final : public Mapping { + public: + SymbolMapping(fml::RefPtr native_library, + const char* symbol_name); + + ~SymbolMapping() override; + + // |Mapping| + size_t GetSize() const override; + + // |Mapping| + const uint8_t* GetMapping() const override; + + private: + fml::RefPtr native_library_; + const uint8_t* mapping_ = nullptr; + + FML_DISALLOW_COPY_AND_ASSIGN(SymbolMapping); +}; + } // namespace fml #endif // FLUTTER_FML_MAPPING_H_ diff --git a/fml/message_loop.cc b/fml/message_loop.cc index 469d47207566a..652fb659bd2c1 100644 --- a/fml/message_loop.cc +++ b/fml/message_loop.cc @@ -6,6 +6,7 @@ #include +#include "flutter/fml/concurrent_message_loop.h" #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/memory/ref_ptr.h" #include "flutter/fml/message_loop_impl.h" @@ -14,12 +15,10 @@ namespace fml { -FML_THREAD_LOCAL ThreadLocal tls_message_loop([](intptr_t value) { - delete reinterpret_cast(value); -}); +FML_THREAD_LOCAL ThreadLocalUniquePtr tls_message_loop; MessageLoop& MessageLoop::GetCurrent() { - auto* loop = reinterpret_cast(tls_message_loop.Get()); + auto* loop = tls_message_loop.get(); FML_CHECK(loop != nullptr) << "MessageLoop::EnsureInitializedForCurrentThread was not called on " "this thread prior to message loop use."; @@ -27,15 +26,15 @@ MessageLoop& MessageLoop::GetCurrent() { } void MessageLoop::EnsureInitializedForCurrentThread() { - if (tls_message_loop.Get() != 0) { + if (tls_message_loop.get() != nullptr) { // Already initialized. return; } - tls_message_loop.Set(reinterpret_cast(new MessageLoop())); + tls_message_loop.reset(new MessageLoop()); } bool MessageLoop::IsInitializedForCurrentThread() { - return tls_message_loop.Get() != 0; + return tls_message_loop.get() != nullptr; } MessageLoop::MessageLoop() @@ -45,6 +44,13 @@ MessageLoop::MessageLoop() FML_CHECK(task_runner_); } +MessageLoop::MessageLoop(Type) + : loop_(fml::MakeRefCounted()), + task_runner_(fml::MakeRefCounted(loop_)) { + FML_CHECK(loop_); + FML_CHECK(task_runner_); +} + MessageLoop::~MessageLoop() = default; void MessageLoop::Run() { diff --git a/fml/message_loop.h b/fml/message_loop.h index 6ca54a94c18a3..3400bf47f592d 100644 --- a/fml/message_loop.h +++ b/fml/message_loop.h @@ -18,6 +18,10 @@ class MessageLoop { FML_EMBEDDER_ONLY static MessageLoop& GetCurrent(); + enum class Type { kConcurrent }; + + MessageLoop(Type type); + bool IsValid() const; void Run(); diff --git a/fml/message_loop_impl.cc b/fml/message_loop_impl.cc index 4d2c5bf4ff614..94474fd1af9e0 100644 --- a/fml/message_loop_impl.cc +++ b/fml/message_loop_impl.cc @@ -48,10 +48,6 @@ void MessageLoopImpl::PostTask(fml::closure task, fml::TimePoint target_time) { RegisterTask(task, target_time); } -void MessageLoopImpl::RunExpiredTasksNow() { - RunExpiredTasks(); -} - void MessageLoopImpl::AddTaskObserver(intptr_t key, fml::closure callback) { FML_DCHECK(callback != nullptr); FML_DCHECK(MessageLoop::GetCurrent().GetLoopImpl().get() == this) @@ -112,8 +108,8 @@ void MessageLoopImpl::RegisterTask(fml::closure task, WakeUp(delayed_tasks_.top().target_time); } -void MessageLoopImpl::RunExpiredTasks() { - TRACE_EVENT0("fml", "MessageLoop::RunExpiredTasks"); +void MessageLoopImpl::FlushTasks(FlushType type) { + TRACE_EVENT0("fml", "MessageLoop::FlushTasks"); std::vector invocations; { @@ -131,6 +127,9 @@ void MessageLoopImpl::RunExpiredTasks() { } invocations.emplace_back(std::move(top.task)); delayed_tasks_.pop(); + if (type == FlushType::kSingle) { + break; + } } WakeUp(delayed_tasks_.empty() ? fml::TimePoint::Max() @@ -145,6 +144,14 @@ void MessageLoopImpl::RunExpiredTasks() { } } +void MessageLoopImpl::RunExpiredTasksNow() { + FlushTasks(FlushType::kAll); +} + +void MessageLoopImpl::RunSingleExpiredTaskNow() { + FlushTasks(FlushType::kSingle); +} + MessageLoopImpl::DelayedTask::DelayedTask(size_t p_order, fml::closure p_task, fml::TimePoint p_target_time) diff --git a/fml/message_loop_impl.h b/fml/message_loop_impl.h index 9dab218d0d1db..4248061ad0d8d 100644 --- a/fml/message_loop_impl.h +++ b/fml/message_loop_impl.h @@ -16,6 +16,7 @@ #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/message_loop.h" +#include "flutter/fml/synchronization/thread_annotations.h" #include "flutter/fml/time/time_point.h" namespace fml { @@ -42,10 +43,15 @@ class MessageLoopImpl : public fml::RefCountedThreadSafe { void DoTerminate(); + protected: // Exposed for the embedder shell which allows clients to poll for events // instead of dedicating a thread to the message loop. + friend class MessageLoop; + void RunExpiredTasksNow(); + void RunSingleExpiredTaskNow(); + protected: MessageLoopImpl(); @@ -76,13 +82,17 @@ class MessageLoopImpl : public fml::RefCountedThreadSafe { std::map task_observers_; std::mutex delayed_tasks_mutex_; - DelayedTaskQueue delayed_tasks_; - size_t order_; + DelayedTaskQueue delayed_tasks_ FML_GUARDED_BY(delayed_tasks_mutex_); + size_t order_ FML_GUARDED_BY(delayed_tasks_mutex_); std::atomic_bool terminated_; void RegisterTask(fml::closure task, fml::TimePoint target_time); - void RunExpiredTasks(); + enum class FlushType { + kSingle, + kAll, + }; + void FlushTasks(FlushType type); FML_DISALLOW_COPY_AND_ASSIGN(MessageLoopImpl); }; diff --git a/fml/message_loop_unittests.cc b/fml/message_loop_unittests.cc index d751071b9e8c8..55de92bb15e1a 100644 --- a/fml/message_loop_unittests.cc +++ b/fml/message_loop_unittests.cc @@ -4,9 +4,11 @@ #define FML_USED_ON_EMBEDDER +#include #include #include "flutter/fml/message_loop.h" +#include "flutter/fml/synchronization/count_down_latch.h" #include "flutter/fml/synchronization/waitable_event.h" #include "flutter/fml/task_runner.h" #include "gtest/gtest.h" @@ -278,3 +280,18 @@ TEST(MessageLoop, TaskObserverFire) { ASSERT_TRUE(started); ASSERT_TRUE(terminated); } + +TEST(MessageLoop, CanCreateConcurrentMessageLoop) { + fml::MessageLoop loop(fml::MessageLoop::Type::kConcurrent); + auto task_runner = loop.GetTaskRunner(); + const size_t kCount = 10; + fml::CountDownLatch latch(kCount); + for (size_t i = 0; i < kCount; ++i) { + task_runner->PostTask([&latch]() { + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + std::cout << "Ran on thread: " << std::this_thread::get_id() << std::endl; + latch.CountDown(); + }); + } + latch.Wait(); +} diff --git a/fml/platform/darwin/message_loop_darwin.h b/fml/platform/darwin/message_loop_darwin.h index 94005ae4c931a..fb4c178c071ba 100644 --- a/fml/platform/darwin/message_loop_darwin.h +++ b/fml/platform/darwin/message_loop_darwin.h @@ -25,10 +25,13 @@ class MessageLoopDarwin : public MessageLoopImpl { ~MessageLoopDarwin() override; + // |fml::MessageLoopImpl| void Run() override; + // |fml::MessageLoopImpl| void Terminate() override; + // |fml::MessageLoopImpl| void WakeUp(fml::TimePoint time_point) override; static void OnTimerFire(CFRunLoopTimerRef timer, MessageLoopDarwin* loop); diff --git a/fml/platform/darwin/string_range_sanitization.h b/fml/platform/darwin/string_range_sanitization.h new file mode 100644 index 0000000000000..95c28b76b6380 --- /dev/null +++ b/fml/platform/darwin/string_range_sanitization.h @@ -0,0 +1,29 @@ +// 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. + +#ifndef FLUTTER_FML_STRING_RANGE_SANITIZATION_H_ +#define FLUTTER_FML_STRING_RANGE_SANITIZATION_H_ + +#include + +namespace fml { + +// Returns a range encompassing the grapheme cluster in which |index| is located. +// +// A nil |text| or an index greater than or equal to text.length will result in +// `NSRange(NSNotFound, 0)`. +NSRange RangeForCharacterAtIndex(NSString* text, NSUInteger index); + +// Returns a range encompassing the grapheme clusters falling in |range|. +// +// This method will not alter the length of the input range, but will ensure +// that the range's location is not in the middle of a multi-byte unicode +// sequence. +// +// An invalid range will result in `NSRange(NSNotFound, 0)`. +NSRange RangeForCharactersInRange(NSString* text, NSRange range); + +} // namespace fml + +#endif // FLUTTER_FML_STRING_RANGE_SANITIZATION_H_ diff --git a/fml/platform/darwin/string_range_sanitization.mm b/fml/platform/darwin/string_range_sanitization.mm new file mode 100644 index 0000000000000..2694fdc568524 --- /dev/null +++ b/fml/platform/darwin/string_range_sanitization.mm @@ -0,0 +1,29 @@ +// 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. + +#include "flutter/fml/platform/darwin/string_range_sanitization.h" + +namespace fml { + +NSRange RangeForCharacterAtIndex(NSString* text, NSUInteger index) { + if (text == nil || index >= text.length) { + return NSMakeRange(NSNotFound, 0); + } + if (index < text.length) + return [text rangeOfComposedCharacterSequenceAtIndex:index]; + return NSMakeRange(index, 0); +} + +NSRange RangeForCharactersInRange(NSString* text, NSRange range) { + if (text == nil || range.location + range.length > text.length) { + return NSMakeRange(NSNotFound, 0); + } + NSRange sanitizedRange = [text rangeOfComposedCharacterSequencesForRange:range]; + // We don't want to override the length, we just want to make sure we don't + // select into the middle of a multi-byte character. Taking the + // `sanitizedRange`'s length will end up altering the actual selection. + return NSMakeRange(sanitizedRange.location, range.length); +} + +} // namespace fml diff --git a/fml/platform/darwin/string_range_sanitization_unittests.mm b/fml/platform/darwin/string_range_sanitization_unittests.mm new file mode 100644 index 0000000000000..22d3cc537c9b8 --- /dev/null +++ b/fml/platform/darwin/string_range_sanitization_unittests.mm @@ -0,0 +1,30 @@ +// 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. + +#include + +#include "flutter/fml/platform/darwin/string_range_sanitization.h" +#include "gtest/gtest.h" + +TEST(StringRangeSanitizationTest, CanHandleUnicode) { + auto result = fml::RangeForCharacterAtIndex(@"😠", 1); + EXPECT_EQ(result.location, 0UL); + EXPECT_EQ(result.length, 2UL); +} + +TEST(StringRangeSanitizationTest, HandlesInvalidRanges) { + auto ns_not_found = static_cast(NSNotFound); + EXPECT_EQ(fml::RangeForCharacterAtIndex(@"😠", 3).location, ns_not_found); + EXPECT_EQ(fml::RangeForCharacterAtIndex(@"😠", -1).location, ns_not_found); + EXPECT_EQ(fml::RangeForCharacterAtIndex(nil, 0).location, ns_not_found); + EXPECT_EQ(fml::RangeForCharactersInRange(@"😠", NSMakeRange(1, 2)).location, ns_not_found); + EXPECT_EQ(fml::RangeForCharactersInRange(@"😠", NSMakeRange(3, 0)).location, ns_not_found); + EXPECT_EQ(fml::RangeForCharactersInRange(nil, NSMakeRange(0, 0)).location, ns_not_found); +} + +TEST(StringRangeSanitizationTest, CanHandleUnicodeRange) { + auto result = fml::RangeForCharactersInRange(@"😠", NSMakeRange(1, 0)); + EXPECT_EQ(result.location, 0UL); + EXPECT_EQ(result.length, 0UL); +} diff --git a/fml/platform/linux/message_loop_linux.cc b/fml/platform/linux/message_loop_linux.cc index 483efe59af348..5ed41aef8fa4e 100644 --- a/fml/platform/linux/message_loop_linux.cc +++ b/fml/platform/linux/message_loop_linux.cc @@ -43,6 +43,7 @@ bool MessageLoopLinux::AddOrRemoveTimerSource(bool add) { return ctl_result == 0; } +// |fml::MessageLoopImpl| void MessageLoopLinux::Run() { running_ = true; @@ -71,11 +72,13 @@ void MessageLoopLinux::Run() { } } +// |fml::MessageLoopImpl| void MessageLoopLinux::Terminate() { running_ = false; WakeUp(fml::TimePoint::Now()); } +// |fml::MessageLoopImpl| void MessageLoopLinux::WakeUp(fml::TimePoint time_point) { bool result = TimerRearm(timer_fd_.get(), time_point); FML_DCHECK(result); diff --git a/fml/platform/linux/message_loop_linux.h b/fml/platform/linux/message_loop_linux.h index 32bdb6442789e..5563328b2f5a3 100644 --- a/fml/platform/linux/message_loop_linux.h +++ b/fml/platform/linux/message_loop_linux.h @@ -23,10 +23,13 @@ class MessageLoopLinux : public MessageLoopImpl { ~MessageLoopLinux() override; + // |fml::MessageLoopImpl| void Run() override; + // |fml::MessageLoopImpl| void Terminate() override; + // |fml::MessageLoopImpl| void WakeUp(fml::TimePoint time_point) override; void OnEventFired(); diff --git a/fml/platform/win/file_win.cc b/fml/platform/win/file_win.cc index dfb3d8dd36f30..bad9d052fb942 100644 --- a/fml/platform/win/file_win.cc +++ b/fml/platform/win/file_win.cc @@ -316,6 +316,10 @@ bool TruncateFile(const fml::UniqueFD& file, size_t size) { return true; } +bool FileExists(const fml::UniqueFD& base_directory, const char* path) { + return IsFile(GetAbsolutePath(base_directory, path).c_str()); +} + bool WriteAtomically(const fml::UniqueFD& base_directory, const char* file_name, const Mapping& mapping) { diff --git a/fml/size.h b/fml/size.h new file mode 100644 index 0000000000000..4ffd7f3eec0e6 --- /dev/null +++ b/fml/size.h @@ -0,0 +1,19 @@ +// 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. + +#ifndef FLUTTER_FML_SIZE_H_ +#define FLUTTER_FML_SIZE_H_ + +#include + +namespace fml { + +template +constexpr std::size_t size(T (&array)[N]) { + return N; +} + +} // namespace fml + +#endif // FLUTTER_FML_SIZE_H_ diff --git a/synchronization/semaphore.cc b/fml/synchronization/semaphore.cc similarity index 92% rename from synchronization/semaphore.cc rename to fml/synchronization/semaphore.cc index 4d8e5003d5921..9dff734603aa0 100644 --- a/synchronization/semaphore.cc +++ b/fml/synchronization/semaphore.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/synchronization/semaphore.h" +#include "flutter/fml/synchronization/semaphore.h" #include "flutter/fml/build_config.h" #include "flutter/fml/logging.h" @@ -10,7 +10,7 @@ #if OS_MACOSX #include -namespace flutter { +namespace fml { class PlatformSemaphore { public: @@ -50,12 +50,12 @@ class PlatformSemaphore { FML_DISALLOW_COPY_AND_ASSIGN(PlatformSemaphore); }; -} // namespace flutter +} // namespace fml #elif OS_WIN #include -namespace flutter { +namespace fml { class PlatformSemaphore { public: @@ -91,13 +91,13 @@ class PlatformSemaphore { FML_DISALLOW_COPY_AND_ASSIGN(PlatformSemaphore); }; -} // namespace flutter +} // namespace fml #else #include #include "flutter/fml/eintr_wrapper.h" -namespace flutter { +namespace fml { class PlatformSemaphore { public: @@ -140,11 +140,11 @@ class PlatformSemaphore { FML_DISALLOW_COPY_AND_ASSIGN(PlatformSemaphore); }; -} // namespace flutter +} // namespace fml #endif -namespace flutter { +namespace fml { Semaphore::Semaphore(uint32_t count) : _impl(new PlatformSemaphore(count)) {} @@ -162,4 +162,4 @@ void Semaphore::Signal() { return _impl->Signal(); } -} // namespace flutter +} // namespace fml diff --git a/synchronization/semaphore.h b/fml/synchronization/semaphore.h similarity index 75% rename from synchronization/semaphore.h rename to fml/synchronization/semaphore.h index 594b0a559bc04..b5871017b1330 100644 --- a/synchronization/semaphore.h +++ b/fml/synchronization/semaphore.h @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SYNCHRONIZATION_SEMAPHORE_H_ -#define SYNCHRONIZATION_SEMAPHORE_H_ +#ifndef FLUTTER_FML_SYNCHRONIZATION_SEMAPHORE_H_ +#define FLUTTER_FML_SYNCHRONIZATION_SEMAPHORE_H_ #include #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" -namespace flutter { +namespace fml { class PlatformSemaphore; @@ -33,6 +33,6 @@ class Semaphore { FML_DISALLOW_COPY_AND_ASSIGN(Semaphore); }; -} // namespace flutter +} // namespace fml -#endif // SYNCHRONIZATION_SEMAPHORE_H_ +#endif // FLUTTER_FML_SYNCHRONIZATION_SEMAPHORE_H_ diff --git a/synchronization/semaphore_unittest.cc b/fml/synchronization/semaphore_unittest.cc similarity index 80% rename from synchronization/semaphore_unittest.cc rename to fml/synchronization/semaphore_unittest.cc index 61810b641bee8..e109c6deb1819 100644 --- a/synchronization/semaphore_unittest.cc +++ b/fml/synchronization/semaphore_unittest.cc @@ -4,21 +4,21 @@ #include -#include "flutter/synchronization/semaphore.h" +#include "flutter/fml/synchronization/semaphore.h" #include "gtest/gtest.h" TEST(SemaphoreTest, SimpleValidity) { - flutter::Semaphore sem(100); + fml::Semaphore sem(100); ASSERT_TRUE(sem.IsValid()); } TEST(SemaphoreTest, WaitOnZero) { - flutter::Semaphore sem(0); + fml::Semaphore sem(0); ASSERT_FALSE(sem.TryWait()); } TEST(SemaphoreTest, WaitOnZeroSignalThenWait) { - flutter::Semaphore sem(0); + fml::Semaphore sem(0); ASSERT_FALSE(sem.TryWait()); std::thread thread([&sem]() { sem.Signal(); }); thread.join(); diff --git a/fml/synchronization/thread_checker.h b/fml/synchronization/thread_checker.h deleted file mode 100644 index 3501ac5d4a9e5..0000000000000 --- a/fml/synchronization/thread_checker.h +++ /dev/null @@ -1,71 +0,0 @@ -// 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. - -// A class for checking that the current thread is/isn't the same as an initial -// thread. - -#ifndef FLUTTER_FML_SYNCHRONIZATION_THREAD_CHECKER_H_ -#define FLUTTER_FML_SYNCHRONIZATION_THREAD_CHECKER_H_ - -#include "flutter/fml/build_config.h" - -#if defined(OS_WIN) -#include -#else -#include -#endif - -#include "flutter/fml/logging.h" -#include "flutter/fml/macros.h" - -namespace fml { - -// A simple class that records the identity of the thread that it was created -// on, and at later points can tell if the current thread is the same as its -// creation thread. This class is thread-safe. -// -// Note: Unlike Chromium's |base::ThreadChecker|, this is *not* Debug-only (so -// #ifdef it out if you want something Debug-only). (Rationale: Having a -// |CalledOnValidThread()| that lies in Release builds seems bad. Moreover, -// there's a small space cost to having even an empty class. ) -class ThreadChecker final { - public: -#if defined(OS_WIN) - ThreadChecker() : self_(GetCurrentThreadId()) {} - ~ThreadChecker() {} - - bool IsCreationThreadCurrent() const { return GetCurrentThreadId() == self_; } - - private: - const DWORD self_; - -#else - ThreadChecker() : self_(pthread_self()) {} - ~ThreadChecker() {} - - // Returns true if the current thread is the thread this object was created - // on and false otherwise. - bool IsCreationThreadCurrent() const { - return !!pthread_equal(pthread_self(), self_); - } - - private: - const pthread_t self_; -#endif - - FML_DISALLOW_COPY_AND_ASSIGN(ThreadChecker); -}; - -#ifndef NDEBUG -#define FML_DECLARE_THREAD_CHECKER(c) fml::ThreadChecker c -#define FML_DCHECK_CREATION_THREAD_IS_CURRENT(c) \ - FML_DCHECK((c).IsCreationThreadCurrent()) -#else -#define FML_DECLARE_THREAD_CHECKER(c) -#define FML_DCHECK_CREATION_THREAD_IS_CURRENT(c) ((void)0) -#endif - -} // namespace fml - -#endif // FLUTTER_FML_SYNCHRONIZATION_THREAD_CHECKER_H_ diff --git a/fml/synchronization/thread_checker_unittest.cc b/fml/synchronization/thread_checker_unittest.cc deleted file mode 100644 index 92eb34f166157..0000000000000 --- a/fml/synchronization/thread_checker_unittest.cc +++ /dev/null @@ -1,37 +0,0 @@ -// 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. - -#include "flutter/fml/synchronization/thread_checker.h" - -#include - -#include "gtest/gtest.h" - -namespace fml { -namespace { - -TEST(ThreadCheckerTest, SameThread) { - ThreadChecker checker; - EXPECT_TRUE(checker.IsCreationThreadCurrent()); -} - -// Note: This test depends on |std::thread| being compatible with -// |pthread_self()|. -TEST(ThreadCheckerTest, DifferentThreads) { - ThreadChecker checker1; - EXPECT_TRUE(checker1.IsCreationThreadCurrent()); - - std::thread thread([&checker1]() { - ThreadChecker checker2; - EXPECT_TRUE(checker2.IsCreationThreadCurrent()); - EXPECT_FALSE(checker1.IsCreationThreadCurrent()); - }); - thread.join(); - - // Note: Without synchronization, we can't look at |checker2| from the main - // thread. -} - -} // namespace -} // namespace fml diff --git a/fml/synchronization/waitable_event_unittest.cc b/fml/synchronization/waitable_event_unittest.cc index aa420910d72fe..97b886b6a9a44 100644 --- a/fml/synchronization/waitable_event_unittest.cc +++ b/fml/synchronization/waitable_event_unittest.cc @@ -16,12 +16,6 @@ #include "flutter/fml/macros.h" #include "gtest/gtest.h" -#ifndef arraysize -template -char (&ArraySizeHelper(T (&array)[N]))[N]; -#define arraysize(array) (sizeof(ArraySizeHelper(array))) -#endif - namespace fml { namespace { diff --git a/fml/task_runner.h b/fml/task_runner.h index 04696752c95e3..72c4219029f34 100644 --- a/fml/task_runner.h +++ b/fml/task_runner.h @@ -17,6 +17,8 @@ class MessageLoopImpl; class TaskRunner : public fml::RefCountedThreadSafe { public: + virtual ~TaskRunner(); + virtual void PostTask(fml::closure task); virtual void PostTaskForTime(fml::closure task, fml::TimePoint target_time); @@ -25,8 +27,6 @@ class TaskRunner : public fml::RefCountedThreadSafe { virtual bool RunsTasksOnCurrentThread(); - virtual ~TaskRunner(); - static void RunNowOrPostTask(fml::RefPtr runner, fml::closure task); diff --git a/fml/thread.h b/fml/thread.h index 19a6e5ec3ba43..9d297c2a5502d 100644 --- a/fml/thread.h +++ b/fml/thread.h @@ -24,13 +24,13 @@ class Thread { void Join(); + static void SetCurrentThreadName(const std::string& name); + private: std::unique_ptr thread_; fml::RefPtr task_runner_; std::atomic_bool joined_; - static void SetCurrentThreadName(const std::string& name); - FML_DISALLOW_COPY_AND_ASSIGN(Thread); }; diff --git a/fml/thread_local.cc b/fml/thread_local.cc index d0afbc00186a0..f997ecc05f68b 100644 --- a/fml/thread_local.cc +++ b/fml/thread_local.cc @@ -4,66 +4,32 @@ #include "flutter/fml/thread_local.h" -namespace fml { - #if FML_THREAD_LOCAL_PTHREADS -ThreadLocal::ThreadLocal() : ThreadLocal(nullptr) {} - -ThreadLocal::ThreadLocal(ThreadLocalDestroyCallback destroy) - : destroy_(destroy) { - auto callback = - reinterpret_cast(&ThreadLocal::ThreadLocalDestroy); - FML_CHECK(pthread_key_create(&_key, callback) == 0); -} - -ThreadLocal::~ThreadLocal() { - // This will NOT call the destroy callbacks on thread local values still - // active in other threads. Those must be cleared manually. The usage - // of this class should be similar to the thread_local keyword but with - // with a static storage specifier +#include "flutter/fml/logging.h" - // Collect the container - delete reinterpret_cast(pthread_getspecific(_key)); +namespace fml { +namespace internal { - // Finally, collect the key - FML_CHECK(pthread_key_delete(_key) == 0); +ThreadLocalPointer::ThreadLocalPointer(void (*destroy)(void*)) { + FML_CHECK(pthread_key_create(&key_, destroy) == 0); } -ThreadLocal::Box::Box(ThreadLocalDestroyCallback destroy, intptr_t value) - : destroy_(destroy), value_(value) {} - -ThreadLocal::Box::~Box() = default; - -#else // FML_THREAD_LOCAL_PTHREADS - -ThreadLocal::ThreadLocal() : ThreadLocal(nullptr) {} - -ThreadLocal::ThreadLocal(ThreadLocalDestroyCallback destroy) - : destroy_(destroy), value_(0) {} - -void ThreadLocal::Set(intptr_t value) { - if (value_ == value) { - return; - } - - if (value_ != 0 && destroy_) { - destroy_(value_); - } - - value_ = value; +ThreadLocalPointer::~ThreadLocalPointer() { + FML_CHECK(pthread_key_delete(key_) == 0); } -intptr_t ThreadLocal::Get() { - return value_; +void* ThreadLocalPointer::get() const { + return pthread_getspecific(key_); } -ThreadLocal::~ThreadLocal() { - if (value_ != 0 && destroy_) { - destroy_(value_); - } +void* ThreadLocalPointer::swap(void* ptr) { + void* old_ptr = get(); + FML_CHECK(pthread_setspecific(key_, ptr) == 0); + return old_ptr; } -#endif // FML_THREAD_LOCAL_PTHREADS - +} // namespace internal } // namespace fml + +#endif // FML_THREAD_LOCAL_PTHREADS diff --git a/fml/thread_local.h b/fml/thread_local.h index 4bf518244a6e9..72ef80c8eb326 100644 --- a/fml/thread_local.h +++ b/fml/thread_local.h @@ -5,10 +5,9 @@ #ifndef FLUTTER_FML_THREAD_LOCAL_H_ #define FLUTTER_FML_THREAD_LOCAL_H_ -#include +#include #include "flutter/fml/build_config.h" -#include "flutter/fml/logging.h" #include "flutter/fml/macros.h" #define FML_THREAD_LOCAL_PTHREADS OS_MACOSX || OS_LINUX || OS_ANDROID @@ -19,103 +18,60 @@ namespace fml { -using ThreadLocalDestroyCallback = std::function; - #if FML_THREAD_LOCAL_PTHREADS -// thread_local is unavailable and we have to resort to pthreads. - #define FML_THREAD_LOCAL static -class ThreadLocal { - private: - class Box { - public: - Box(ThreadLocalDestroyCallback destroy, intptr_t value); - - ~Box(); +namespace internal { - intptr_t Value() const { return value_; } - - void SetValue(intptr_t value) { - if (value == value_) { - return; - } - - DestroyValue(); - value_ = value; - } +class ThreadLocalPointer { + public: + ThreadLocalPointer(void (*destroy)(void*)); + ~ThreadLocalPointer(); - void DestroyValue() { - if (destroy_) { - destroy_(value_); - } - } + void* get() const; + void* swap(void* ptr); - private: - ThreadLocalDestroyCallback destroy_; - intptr_t value_; + private: + pthread_key_t key_; - FML_DISALLOW_COPY_AND_ASSIGN(Box); - }; + FML_DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer); +}; - static inline void ThreadLocalDestroy(void* value) { - FML_CHECK(value != nullptr); - auto* box = reinterpret_cast(value); - box->DestroyValue(); - delete box; - } +} // namespace internal +template +class ThreadLocalUniquePtr { public: - ThreadLocal(); - - ThreadLocal(ThreadLocalDestroyCallback destroy); - - void Set(intptr_t value) { - auto* box = reinterpret_cast(pthread_getspecific(_key)); - if (box == nullptr) { - box = new Box(destroy_, value); - FML_CHECK(pthread_setspecific(_key, box) == 0); - } else { - box->SetValue(value); - } - } - - intptr_t Get() { - auto* box = reinterpret_cast(pthread_getspecific(_key)); - return box != nullptr ? box->Value() : 0; - } + ThreadLocalUniquePtr() : ptr_(destroy) {} - ~ThreadLocal(); + T* get() const { return reinterpret_cast(ptr_.get()); } + void reset(T* ptr) { destroy(ptr_.swap(ptr)); } private: - pthread_key_t _key; - ThreadLocalDestroyCallback destroy_; + static void destroy(void* ptr) { delete reinterpret_cast(ptr); } - FML_DISALLOW_COPY_AND_ASSIGN(ThreadLocal); + internal::ThreadLocalPointer ptr_; + + FML_DISALLOW_COPY_AND_ASSIGN(ThreadLocalUniquePtr); }; #else // FML_THREAD_LOCAL_PTHREADS -#define FML_THREAD_LOCAL thread_local +#define FML_THREAD_LOCAL static thread_local -class ThreadLocal { +template +class ThreadLocalUniquePtr { public: - ThreadLocal(); - - ThreadLocal(ThreadLocalDestroyCallback destroy); - - void Set(intptr_t value); - - intptr_t Get(); + ThreadLocalUniquePtr() = default; - ~ThreadLocal(); + T* get() const { return ptr_.get(); } + void reset(T* ptr) { ptr_.reset(ptr); } private: - ThreadLocalDestroyCallback destroy_; - intptr_t value_; + std::unique_ptr ptr_; - FML_DISALLOW_COPY_AND_ASSIGN(ThreadLocal); + FML_DISALLOW_COPY_AND_ASSIGN(ThreadLocalUniquePtr); }; #endif // FML_THREAD_LOCAL_PTHREADS diff --git a/fml/thread_local_unittests.cc b/fml/thread_local_unittests.cc index 7f48cfcd532f6..e0e026b3b76db 100644 --- a/fml/thread_local_unittests.cc +++ b/fml/thread_local_unittests.cc @@ -2,108 +2,103 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include #include -#include "flutter/fml/logging.h" +#include "flutter/fml/macros.h" #include "flutter/fml/thread_local.h" #include "gtest/gtest.h" -// We are only going to test the pthreads based thread local boxes. -#if FML_THREAD_LOCAL_PTHREADS +namespace { + +class Box { + public: + Box(int value, std::atomic_int* destroys = nullptr) + : value_(value), destroys_(destroys) {} + ~Box() { + if (destroys_) { + ++*destroys_; + } + } + + int value() const { return value_; } + + private: + int value_; + std::atomic_int* destroys_; + + FML_DISALLOW_COPY_AND_ASSIGN(Box); +}; + +FML_THREAD_LOCAL fml::ThreadLocalUniquePtr local; + +} // namespace TEST(ThreadLocal, SimpleInitialization) { std::thread thread([&] { - fml::ThreadLocal local; + ASSERT_EQ(local.get(), nullptr); auto value = 100; - local.Set(value); - ASSERT_EQ(local.Get(), value); + local.reset(new Box(value)); + ASSERT_EQ(local.get()->value(), value); }); thread.join(); } TEST(ThreadLocal, SimpleInitializationCheckInAnother) { std::thread thread([&] { - fml::ThreadLocal local; + ASSERT_EQ(local.get(), nullptr); auto value = 100; - local.Set(value); - ASSERT_EQ(local.Get(), value); - std::thread thread2([&]() { ASSERT_EQ(local.Get(), 0); }); + local.reset(new Box(value)); + ASSERT_EQ(local.get()->value(), value); + std::thread thread2([&]() { ASSERT_EQ(local.get(), nullptr); }); thread2.join(); }); thread.join(); } TEST(ThreadLocal, DestroyCallback) { + std::atomic_int destroys{0}; std::thread thread([&] { - int destroys = 0; - fml::ThreadLocal local([&destroys](intptr_t) { destroys++; }); + ASSERT_EQ(local.get(), nullptr); auto value = 100; - local.Set(value); - ASSERT_EQ(local.Get(), value); - ASSERT_EQ(destroys, 0); + local.reset(new Box(value, &destroys)); + ASSERT_EQ(local.get()->value(), value); + ASSERT_EQ(destroys.load(), 0); }); thread.join(); + ASSERT_EQ(destroys.load(), 1); } TEST(ThreadLocal, DestroyCallback2) { + std::atomic_int destroys{0}; std::thread thread([&] { - int destroys = 0; - fml::ThreadLocal local([&destroys](intptr_t) { destroys++; }); - - local.Set(100); - ASSERT_EQ(local.Get(), 100); - ASSERT_EQ(destroys, 0); - local.Set(200); - ASSERT_EQ(local.Get(), 200); - ASSERT_EQ(destroys, 1); + local.reset(new Box(100, &destroys)); + ASSERT_EQ(local.get()->value(), 100); + ASSERT_EQ(destroys.load(), 0); + local.reset(new Box(200, &destroys)); + ASSERT_EQ(local.get()->value(), 200); + ASSERT_EQ(destroys.load(), 1); }); thread.join(); + ASSERT_EQ(destroys.load(), 2); } TEST(ThreadLocal, DestroyThreadTimeline) { + std::atomic_int destroys{0}; std::thread thread([&] { - int destroys = 0; - fml::ThreadLocal local([&destroys](intptr_t) { destroys++; }); - - std::thread thread([&]() { - local.Set(100); - ASSERT_EQ(local.Get(), 100); - ASSERT_EQ(destroys, 0); - local.Set(200); - ASSERT_EQ(local.Get(), 200); - ASSERT_EQ(destroys, 1); + std::thread thread2([&]() { + local.reset(new Box(100, &destroys)); + ASSERT_EQ(local.get()->value(), 100); + ASSERT_EQ(destroys.load(), 0); + local.reset(new Box(200, &destroys)); + ASSERT_EQ(local.get()->value(), 200); + ASSERT_EQ(destroys.load(), 1); }); - ASSERT_EQ(local.Get(), 0); - thread.join(); - ASSERT_EQ(local.Get(), 0); - ASSERT_EQ(destroys, 2); - }); - thread.join(); -} - -TEST(ThreadLocal, SettingSameValue) { - std::thread thread([&] { - int destroys = 0; - { - fml::ThreadLocal local([&destroys](intptr_t) { destroys++; }); - - local.Set(100); - ASSERT_EQ(destroys, 0); - local.Set(100); - local.Set(100); - local.Set(100); - ASSERT_EQ(local.Get(), 100); - local.Set(100); - local.Set(100); - ASSERT_EQ(destroys, 0); - local.Set(200); - ASSERT_EQ(destroys, 1); - ASSERT_EQ(local.Get(), 200); - } - - ASSERT_EQ(destroys, 1); + ASSERT_EQ(local.get(), nullptr); + thread2.join(); + ASSERT_EQ(local.get(), nullptr); + ASSERT_EQ(destroys.load(), 2); }); thread.join(); + ASSERT_EQ(destroys.load(), 2); } - -#endif // FML_THREAD_LOCAL_PTHREADS diff --git a/fml/time/time_point.cc b/fml/time/time_point.cc index f0a912e92fdee..d097338c359d4 100644 --- a/fml/time/time_point.cc +++ b/fml/time/time_point.cc @@ -6,71 +6,31 @@ #include "flutter/fml/build_config.h" -#if defined(OS_MACOSX) || defined(OS_IOS) -#include -#include -#elif defined(OS_FUCHSIA) +#if defined(OS_FUCHSIA) #include -#elif defined(OS_WIN) -#include #else -#include -#endif // defined(OS_MACOSX) || defined(OS_IOS) - -#include "flutter/fml/logging.h" +#include +#endif namespace fml { -// Mac OS X/iOS don't have a (useful) |clock_gettime()|. -// Note: Chromium's |base::TimeTicks::Now()| uses boot time (obtained via -// |sysctl()| with |CTL_KERN|/|KERN_BOOTTIME|). For our current purposes, -// monotonic time (which pauses during sleeps) is sufficient. TODO(vtl): If/when -// we use this for other purposes, maybe we should use boot time (maybe also on -// POSIX). -#if defined(OS_MACOSX) || defined(OS_IOS) - -mach_timebase_info_data_t GetMachTimebaseInfo() { - mach_timebase_info_data_t timebase_info = {}; - kern_return_t error = mach_timebase_info(&timebase_info); - FML_DCHECK(error == KERN_SUCCESS); - return timebase_info; -} - -// static -TimePoint TimePoint::Now() { - static mach_timebase_info_data_t timebase_info = GetMachTimebaseInfo(); - return TimePoint(mach_absolute_time() * timebase_info.numer / - timebase_info.denom); -} - -#elif defined(OS_FUCHSIA) +#if defined(OS_FUCHSIA) // static TimePoint TimePoint::Now() { return TimePoint(zx_clock_get(ZX_CLOCK_MONOTONIC)); } -#elif defined(OS_WIN) - -TimePoint TimePoint::Now() { - uint64_t freq = 0; - uint64_t count = 0; - QueryPerformanceFrequency((LARGE_INTEGER*)&freq); - QueryPerformanceCounter((LARGE_INTEGER*)&count); - return TimePoint((count * 1000000000) / freq); -} - #else -// static TimePoint TimePoint::Now() { - struct timespec ts; - int res = clock_gettime(CLOCK_MONOTONIC, &ts); - FML_DCHECK(res == 0); - (void)res; - return TimePoint::FromEpochDelta(TimeDelta::FromTimespec(ts)); + // The base time is arbitrary; use the clock epoch for convenience. + const auto elapsed_time = std::chrono::steady_clock::now().time_since_epoch(); + return TimePoint( + std::chrono::duration_cast(elapsed_time) + .count()); } -#endif // defined(OS_MACOSX) || defined(OS_IOS) +#endif } // namespace fml diff --git a/fml/trace_event.cc b/fml/trace_event.cc index 69ed8b2216486..826e37f189eca 100644 --- a/fml/trace_event.cc +++ b/fml/trace_event.cc @@ -4,27 +4,72 @@ #include "flutter/fml/trace_event.h" -#include "third_party/dart/runtime/include/dart_tools_api.h" +#include +#include +#include + +#include "flutter/fml/build_config.h" +#include "flutter/fml/logging.h" + +#if OS_MACOSX && !defined(NDEBUG) + +#include + +#define DCHECK_LITERAL(x) \ + ({ \ + do { \ + FML_DCHECK(malloc_size((x)) == 0) \ + << "Timeline string must not be on the heap."; \ + } while (0); \ + ((x)); \ + }) + +#else // OS_MACOSX + +#define DCHECK_LITERAL(x) ((x)) + +#endif // OS_MACOSX namespace fml { namespace tracing { -void TraceCounter(TraceArg category_group, TraceArg name, TraceIDArg count) { - auto count_string = std::to_string(count); - const char* arg_names[] = {name}; - const char* arg_values[] = {count_string.c_str()}; - Dart_TimelineEvent(name, // label - Dart_TimelineGetMicros(), // timestamp0 - 0, // timestamp1_or_async_id - Dart_Timeline_Event_Counter, // event type - 1, // argument_count - arg_names, // argument_names - arg_values // argument_values +size_t TraceNonce() { + static std::atomic_size_t gLastItem; + return ++gLastItem; +} + +void TraceTimelineEvent(TraceArg category_group, + TraceArg name, + TraceIDArg identifier, + Dart_Timeline_Event_Type type, + const std::vector& c_names, + const std::vector& values) { + const auto argument_count = std::min(c_names.size(), values.size()); + + std::vector c_values; + c_values.resize(argument_count, nullptr); + + for (size_t i = 0; i < argument_count; i++) { +#if !defined(NDEBUG) + DCHECK_LITERAL(c_names[i]); +#endif // !defined(NDEBUG) + + c_values[i] = values[i].c_str(); + } + + Dart_TimelineEvent( + DCHECK_LITERAL(name), // label + Dart_TimelineGetMicros(), // timestamp0 + identifier, // timestamp1_or_async_id + type, // event type + argument_count, // argument_count + const_cast(c_names.data()), // argument_names + c_values.data() // argument_values ); } void TraceEvent0(TraceArg category_group, TraceArg name) { - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 0, // timestamp1_or_async_id Dart_Timeline_Event_Begin, // event type @@ -38,9 +83,9 @@ void TraceEvent1(TraceArg category_group, TraceArg name, TraceArg arg1_name, TraceArg arg1_val) { - const char* arg_names[] = {arg1_name}; + const char* arg_names[] = {DCHECK_LITERAL(arg1_name)}; const char* arg_values[] = {arg1_val}; - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 0, // timestamp1_or_async_id Dart_Timeline_Event_Begin, // event type @@ -56,9 +101,10 @@ void TraceEvent2(TraceArg category_group, TraceArg arg1_val, TraceArg arg2_name, TraceArg arg2_val) { - const char* arg_names[] = {arg1_name, arg2_name}; + const char* arg_names[] = {DCHECK_LITERAL(arg1_name), + DCHECK_LITERAL(arg2_name)}; const char* arg_values[] = {arg1_val, arg2_val}; - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 0, // timestamp1_or_async_id Dart_Timeline_Event_Begin, // event type @@ -69,7 +115,7 @@ void TraceEvent2(TraceArg category_group, } void TraceEventEnd(TraceArg name) { - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 0, // timestamp1_or_async_id Dart_Timeline_Event_End, // event type @@ -79,10 +125,38 @@ void TraceEventEnd(TraceArg name) { ); } +void TraceEventAsyncComplete(TraceArg category_group, + TraceArg name, + TimePoint begin, + TimePoint end) { + auto identifier = TraceNonce(); + + if (begin > end) { + std::swap(begin, end); + } + + Dart_TimelineEvent(DCHECK_LITERAL(name), // label + begin.ToEpochDelta().ToMicroseconds(), // timestamp0 + identifier, // timestamp1_or_async_id + Dart_Timeline_Event_Async_Begin, // event type + 0, // argument_count + nullptr, // argument_names + nullptr // argument_values + ); + Dart_TimelineEvent(DCHECK_LITERAL(name), // label + end.ToEpochDelta().ToMicroseconds(), // timestamp0 + identifier, // timestamp1_or_async_id + Dart_Timeline_Event_Async_End, // event type + 0, // argument_count + nullptr, // argument_names + nullptr // argument_values + ); +} + void TraceEventAsyncBegin0(TraceArg category_group, TraceArg name, TraceIDArg id) { - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 id, // timestamp1_or_async_id Dart_Timeline_Event_Async_Begin, // event type @@ -95,7 +169,7 @@ void TraceEventAsyncBegin0(TraceArg category_group, void TraceEventAsyncEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) { - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 id, // timestamp1_or_async_id Dart_Timeline_Event_Async_End, // event type @@ -110,9 +184,9 @@ void TraceEventAsyncBegin1(TraceArg category_group, TraceIDArg id, TraceArg arg1_name, TraceArg arg1_val) { - const char* arg_names[] = {arg1_name}; + const char* arg_names[] = {DCHECK_LITERAL(arg1_name)}; const char* arg_values[] = {arg1_val}; - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 id, // timestamp1_or_async_id Dart_Timeline_Event_Async_Begin, // event type @@ -127,9 +201,9 @@ void TraceEventAsyncEnd1(TraceArg category_group, TraceIDArg id, TraceArg arg1_name, TraceArg arg1_val) { - const char* arg_names[] = {arg1_name}; + const char* arg_names[] = {DCHECK_LITERAL(arg1_name)}; const char* arg_values[] = {arg1_val}; - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 id, // timestamp1_or_async_id Dart_Timeline_Event_Async_End, // event type @@ -140,7 +214,7 @@ void TraceEventAsyncEnd1(TraceArg category_group, } void TraceEventInstant0(TraceArg category_group, TraceArg name) { - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 0, // timestamp1_or_async_id Dart_Timeline_Event_Instant, // event type @@ -153,7 +227,7 @@ void TraceEventInstant0(TraceArg category_group, TraceArg name) { void TraceEventFlowBegin0(TraceArg category_group, TraceArg name, TraceIDArg id) { - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 id, // timestamp1_or_async_id Dart_Timeline_Event_Flow_Begin, // event type @@ -166,7 +240,7 @@ void TraceEventFlowBegin0(TraceArg category_group, void TraceEventFlowStep0(TraceArg category_group, TraceArg name, TraceIDArg id) { - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 id, // timestamp1_or_async_id Dart_Timeline_Event_Flow_Step, // event type @@ -177,7 +251,7 @@ void TraceEventFlowStep0(TraceArg category_group, } void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) { - Dart_TimelineEvent(name, // label + Dart_TimelineEvent(DCHECK_LITERAL(name), // label Dart_TimelineGetMicros(), // timestamp0 id, // timestamp1_or_async_id Dart_Timeline_Event_Flow_End, // event type diff --git a/fml/trace_event.h b/fml/trace_event.h index b3bba9b281f61..9f86bcfa04b0c 100644 --- a/fml/trace_event.h +++ b/fml/trace_event.h @@ -8,13 +8,17 @@ #include "flutter/fml/build_config.h" #if defined(OS_FUCHSIA) +#if !defined(FUCHSIA_SDK) // Forward to the system tracing mechanism on Fuchsia. #include -#define FML_TRACE_COUNTER(category_group, name, count) \ - TRACE_COUNTER(category_group, name, 0u, name, count) +// TODO(DNO-448): This is disabled because the Fuchsia counter id json parsing +// only handles ints whereas this can produce ints or strings. +#define FML_TRACE_COUNTER(a, b, c, args...) +#define FML_TRACE_EVENT(a, b, args...) TRACE_DURATION(a, b) + #define TRACE_EVENT0(a, b) TRACE_DURATION(a, b) #define TRACE_EVENT1(a, b, c, d) TRACE_DURATION(a, b, c, d) #define TRACE_EVENT2(a, b, c, d, e, f) TRACE_DURATION(a, b, c, d, e, f) @@ -22,17 +26,22 @@ #define TRACE_EVENT_ASYNC_END0(a, b, c) TRACE_ASYNC_END(a, b, c) #define TRACE_EVENT_ASYNC_BEGIN1(a, b, c, d, e) TRACE_ASYNC_BEGIN(a, b, c, d, e) #define TRACE_EVENT_ASYNC_END1(a, b, c, d, e) TRACE_ASYNC_END(a, b, c, d, e) +#define TRACE_EVENT_INSTANT0(a, b) TRACE_INSTANT(a, b, TRACE_SCOPE_THREAD) -#endif // defined(OS_FUCHSIA) +#endif // !defined(FUCHSIA_SDK) +#endif // defined(OS_FUCHSIA) #include #include #include +#include +#include #include "flutter/fml/macros.h" +#include "flutter/fml/time/time_point.h" +#include "third_party/dart/runtime/include/dart_tools_api.h" -#if !defined(OS_FUCHSIA) - +#if !defined(OS_FUCHSIA) || defined(FUCHSIA_SDK) #ifndef TRACE_EVENT_HIDE_MACROS #define __FML__TOKEN_CAT__(x, y) x##y @@ -45,8 +54,13 @@ // from trace/event.h on Fuchsia. // // TODO(chinmaygarde): All macros here should have the FML prefix. -#define FML_TRACE_COUNTER(category_group, name, count) \ - ::fml::tracing::TraceCounter(category_group, name, count); +#define FML_TRACE_COUNTER(category_group, name, counter_id, arg1, ...) \ + ::fml::tracing::TraceCounter((category_group), (name), (counter_id), (arg1), \ + __VA_ARGS__); + +#define FML_TRACE_EVENT(category_group, name, ...) \ + ::fml::tracing::TraceEvent((category_group), (name), __VA_ARGS__); \ + __FML__AUTO_TRACE_END(name) #define TRACE_EVENT0(category_group, name) \ ::fml::tracing::TraceEvent0(category_group, name); \ @@ -90,8 +104,7 @@ ::fml::tracing::TraceEventFlowEnd0(category, name, id); #endif // TRACE_EVENT_HIDE_MACROS - -#endif // !defined(OS_FUCHSIA) +#endif // !defined(OS_FUCHSIA) || defined(FUCHSIA_SDK) namespace fml { namespace tracing { @@ -99,7 +112,76 @@ namespace tracing { using TraceArg = const char*; using TraceIDArg = int64_t; -void TraceCounter(TraceArg category_group, TraceArg name, TraceIDArg count); +void TraceTimelineEvent(TraceArg category_group, + TraceArg name, + TraceIDArg id, + Dart_Timeline_Event_Type type, + const std::vector& names, + const std::vector& values); + +inline std::string TraceToString(const char* string) { + return std::string{string}; +} + +inline std::string TraceToString(std::string string) { + return string; +} + +inline std::string TraceToString(TimePoint point) { + return std::to_string(point.ToEpochDelta().ToNanoseconds()); +} + +template ::value>> +std::string TraceToString(T string) { + return std::to_string(string); +} + +inline void SplitArgumentsCollect(std::vector& keys, + std::vector& values) {} + +template +void SplitArgumentsCollect(std::vector& keys, + std::vector& values, + Key key, + Value value, + Args... args) { + keys.emplace_back(key); + values.emplace_back(TraceToString(value)); + SplitArgumentsCollect(keys, values, args...); +} + +inline std::pair, std::vector> +SplitArguments() { + return {}; +} + +template +std::pair, std::vector> +SplitArguments(Key key, Value value, Args... args) { + std::vector keys; + std::vector values; + SplitArgumentsCollect(keys, values, key, value, args...); + return std::make_pair(std::move(keys), std::move(values)); +} + +size_t TraceNonce(); + +template +void TraceCounter(TraceArg category, + TraceArg name, + TraceIDArg identifier, + Args... args) { + auto split = SplitArguments(args...); + TraceTimelineEvent(category, name, identifier, Dart_Timeline_Event_Counter, + split.first, split.second); +} + +template +void TraceEvent(TraceArg category, TraceArg name, Args... args) { + auto split = SplitArguments(args...); + TraceTimelineEvent(category, name, 0, Dart_Timeline_Event_Begin, split.first, + split.second); +} void TraceEvent0(TraceArg category_group, TraceArg name); @@ -117,6 +199,11 @@ void TraceEvent2(TraceArg category_group, void TraceEventEnd(TraceArg name); +void TraceEventAsyncComplete(TraceArg category_group, + TraceArg name, + TimePoint begin, + TimePoint end); + void TraceEventAsyncBegin0(TraceArg category_group, TraceArg name, TraceIDArg id); @@ -147,12 +234,12 @@ void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id); class ScopedInstantEnd { public: - ScopedInstantEnd(std::string str) : label_(std::move(str)) {} + ScopedInstantEnd(const char* str) : label_(str) {} - ~ScopedInstantEnd() { TraceEventEnd(label_.c_str()); } + ~ScopedInstantEnd() { TraceEventEnd(label_); } private: - const std::string label_; + const char* label_; FML_DISALLOW_COPY_AND_ASSIGN(ScopedInstantEnd); }; diff --git a/fml/unique_object.h b/fml/unique_object.h index f42603ef80451..407502a0703b8 100644 --- a/fml/unique_object.h +++ b/fml/unique_object.h @@ -14,10 +14,10 @@ namespace fml { // struct UniqueFooTraits { -// // This function should be fast an inline. +// // This function should be fast and inline. // static int InvalidValue() { return 0; } // -// // This function should be fast an inline. +// // This function should be fast and inline. // static bool IsValid(const T& value) { return value != InvalidValue(); } // // // This free function will not be called if f == InvalidValue()! diff --git a/frontend_server/BUILD.gn b/frontend_server/BUILD.gn index 96a92ed0a04fa..21660d2976c76 100644 --- a/frontend_server/BUILD.gn +++ b/frontend_server/BUILD.gn @@ -15,14 +15,14 @@ if (is_fuchsia_host || is_fuchsia) { ] deps = [ + "//third_party/dart-pkg/pub/args", + "//third_party/dart-pkg/pub/path", + "//third_party/dart-pkg/pub/usage", "//third_party/dart/pkg/build_integration", "//third_party/dart/pkg/front_end", "//third_party/dart/pkg/kernel", "//third_party/dart/pkg/vm", - "//third_party/dart-pkg/pub/args", - "//third_party/dart-pkg/pub/path", - "//third_party/dart-pkg/pub/usage", - "//third_party/flutter/flutter_kernel_transformers" + "//third_party/flutter/flutter_kernel_transformers", ] } @@ -48,16 +48,34 @@ if (is_fuchsia_host || is_fuchsia) { ] dot_packages = rebase_path(".packages") flutter_patched_sdk = rebase_path("$root_out_dir/flutter_patched_sdk") - training_args = [ "--train", "--sdk-root=$flutter_patched_sdk" ] + training_args = [ + "--train", + "--sdk-root=$flutter_patched_sdk", + ] - frontend_server_files = exec_script("//third_party/dart/tools/list_dart_files.py", - [ "absolute", rebase_path("."), ], "list lines") + frontend_server_files = + exec_script("//third_party/dart/tools/list_dart_files.py", + [ + "absolute", + rebase_path("."), + ], + "list lines") - frontend_server_files += exec_script("//third_party/dart/tools/list_dart_files.py", - [ "absolute", rebase_path("../flutter_kernel_transformers"), ], "list lines") + frontend_server_files += + exec_script("//third_party/dart/tools/list_dart_files.py", + [ + "absolute", + rebase_path("../flutter_kernel_transformers"), + ], + "list lines") - frontend_server_files += exec_script("//third_party/dart/tools/list_dart_files.py", - [ "absolute", rebase_path("../../third_party/dart/pkg"), ], "list lines") + frontend_server_files += + exec_script("//third_party/dart/tools/list_dart_files.py", + [ + "absolute", + rebase_path("../../third_party/dart/pkg"), + ], + "list lines") inputs = frontend_server_files } diff --git a/frontend_server/lib/server.dart b/frontend_server/lib/server.dart index 5d84d2dcf95ba..44a3d69b9456e 100644 --- a/frontend_server/lib/server.dart +++ b/frontend_server/lib/server.dart @@ -21,9 +21,9 @@ class _FlutterFrontendCompiler implements frontend.CompilerInterface{ final frontend.CompilerInterface _compiler; _FlutterFrontendCompiler(StringSink output, - {bool trackWidgetCreation: false, bool unsafePackageSerialization}) : - _compiler = new frontend.FrontendCompiler(output, - transformer: trackWidgetCreation ? new WidgetCreatorTracker() : null, + {bool trackWidgetCreation = false, bool unsafePackageSerialization}) : + _compiler = frontend.FrontendCompiler(output, + transformer: trackWidgetCreation ? WidgetCreatorTracker() : null, unsafePackageSerialization: unsafePackageSerialization); @override @@ -32,8 +32,8 @@ class _FlutterFrontendCompiler implements frontend.CompilerInterface{ } @override - Future recompileDelta({String filename}) async { - return _compiler.recompileDelta(filename: filename); + Future recompileDelta({String entryPoint}) async { + return _compiler.recompileDelta(entryPoint: entryPoint); } @override @@ -108,7 +108,7 @@ Future starter( '--sdk-root=$sdkRoot', '--output-dill=$outputTrainingDill', '--target=flutter']); - compiler ??= new _FlutterFrontendCompiler(output, trackWidgetCreation: true); + compiler ??= _FlutterFrontendCompiler(output, trackWidgetCreation: true); await compiler.compile(Platform.script.toFilePath(), options); compiler.acceptLastDelta(); @@ -125,7 +125,7 @@ Future starter( } } - compiler ??= new _FlutterFrontendCompiler(output, + compiler ??= _FlutterFrontendCompiler(output, trackWidgetCreation: options['track-widget-creation'], unsafePackageSerialization: options['unsafe-package-serialization']); @@ -133,7 +133,7 @@ Future starter( return await compiler.compile(options.rest[0], options) ? 0 : 254; } - final Completer completer = new Completer(); + final Completer completer = Completer(); frontend.listenAndCompile(compiler, input ?? stdin, options, completer); return completer.future; } diff --git a/frontend_server/test/server_test.dart b/frontend_server/test/server_test.dart index 9e98639b671d9..ce00035c81833 100644 --- a/frontend_server/test/server_test.dart +++ b/frontend_server/test/server_test.dart @@ -9,7 +9,7 @@ class _MockedCompiler extends Mock implements frontend.CompilerInterface {} Future main() async { group('basic', () { - final frontend.CompilerInterface compiler = new _MockedCompiler(); + final frontend.CompilerInterface compiler = _MockedCompiler(); test('train with mocked compiler completes', () async { expect(await starter(['--train'], compiler: compiler), equals(0)); diff --git a/lib/io/dart_io.cc b/lib/io/dart_io.cc index 1b1866b4e8569..70dd8d1f1c630 100644 --- a/lib/io/dart_io.cc +++ b/lib/io/dart_io.cc @@ -10,16 +10,15 @@ using tonic::ToDart; -namespace blink { +namespace flutter { void DartIO::InitForIsolate() { - DART_CHECK_VALID(Dart_SetNativeResolver(Dart_LookupLibrary(ToDart("dart:io")), - dart::bin::LookupIONative, - dart::bin::LookupIONativeSymbol)); + Dart_Handle result = Dart_SetNativeResolver( + Dart_LookupLibrary(ToDart("dart:io")), dart::bin::LookupIONative, + dart::bin::LookupIONativeSymbol); + if (Dart_IsError(result)) { + Dart_PropagateError(result); + } } -bool DartIO::EntropySource(uint8_t* buffer, intptr_t length) { - return dart::bin::GetEntropy(buffer, length); -} - -} // namespace blink +} // namespace flutter diff --git a/lib/io/dart_io.h b/lib/io/dart_io.h index 6d2a36abbbf45..10fe07b514744 100644 --- a/lib/io/dart_io.h +++ b/lib/io/dart_io.h @@ -9,17 +9,16 @@ #include "flutter/fml/macros.h" -namespace blink { +namespace flutter { class DartIO { public: static void InitForIsolate(); - static bool EntropySource(uint8_t* buffer, intptr_t length); private: FML_DISALLOW_IMPLICIT_CONSTRUCTORS(DartIO); }; -} // namespace blink +} // namespace flutter #endif // FLUTTER_LIB_IO_DART_IO_H_ diff --git a/lib/snapshot/BUILD.gn b/lib/snapshot/BUILD.gn index 4db8600eab7fd..878fbf217d73d 100644 --- a/lib/snapshot/BUILD.gn +++ b/lib/snapshot/BUILD.gn @@ -2,21 +2,16 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("$flutter_root/lib/ui/dart_ui.gni") import("//build/compiled_action.gni") +import("//build/fuchsia/sdk.gni") import("//third_party/dart/utils/compile_platform.gni") - -if (is_fuchsia) { - import("//build/dart/dart_library.gni") - import("//build/dart/toolchain.gni") - import("//topaz/public/dart-pkg/fuchsia/sdk_ext.gni") - import("//topaz/public/dart-pkg/zircon/sdk_ext.gni") - import("//topaz/public/lib/ui/flutter/sdk_ext/sdk_ext.gni") -} +import("$flutter_root/common/config.gni") +import("$flutter_root/lib/ui/dart_ui.gni") bindings_output_dir = "$root_gen_dir/sky/bindings" copy("generate_dart_ui") { + visibility = [ ":*" ] sources = dart_ui_files outputs = [ @@ -27,8 +22,9 @@ copy("generate_dart_ui") { compiled_action("generate_snapshot_bin") { tool = "//third_party/dart/runtime/bin:gen_snapshot" - if (is_fuchsia || is_fuchsia_host) { - platform_kernel = "$root_out_dir/flutter_runner_patched_sdk/platform_strong.dill" + if ((is_fuchsia || is_fuchsia_host) && !using_fuchsia_sdk) { + platform_kernel = + "$root_out_dir/flutter_runner_patched_sdk/platform_strong.dill" } else { platform_kernel = "$root_out_dir/flutter_patched_sdk/platform_strong.dill" } @@ -60,17 +56,13 @@ compiled_action("generate_snapshot_bin") { "--isolate_snapshot_data=" + rebase_path(isolate_snapshot_data), "--isolate_snapshot_instructions=" + rebase_path(isolate_snapshot_instructions), - rebase_path(platform_kernel), ] if (is_debug) { - args += [ - "--enable_asserts", - "--enable_type_checks", - "--error_on_bad_type", - "--error_on_bad_override", - ] + args += [ "--enable_asserts" ] } + + args += [ rebase_path(platform_kernel) ] } # Generates an assembly file defining a given symbol with the bytes from a @@ -79,23 +71,31 @@ compiled_action("generate_snapshot_bin") { template("bin_to_assembly") { assert(defined(invoker.deps), "Must define deps") assert(defined(invoker.input), "Must define input binary file") - assert(defined(invoker.output), "Must define output assembly file") assert(defined(invoker.symbol), "Must define symbol name") assert(defined(invoker.executable), "Must define boolean executable") action(target_name) { deps = invoker.deps script = "//third_party/dart/runtime/tools/bin_to_assembly.py" + output = invoker.input + ".S" args = [ "--input", rebase_path(invoker.input), "--output", - rebase_path(invoker.output), + rebase_path(output), "--symbol_name", invoker.symbol, "--target_os", current_os, ] + if (defined(invoker.size_symbol)) { + args += [ + "--size_symbol_name", + invoker.size_symbol, + "--target_arch", + current_cpu, + ] + } if (invoker.executable) { args += [ "--executable" ] } @@ -104,70 +104,139 @@ template("bin_to_assembly") { invoker.input, ] outputs = [ - invoker.output, + output, ] } } -bin_to_assembly("vm_snapshot_data_assembly") { +# Generates an object file defining a given symbol with the bytes from a +# binary file. Places the symbol in the read-only data section. +template("bin_to_coff") { + assert(defined(invoker.deps), "Must define deps") + assert(defined(invoker.input), "Must define input binary file") + assert(defined(invoker.symbol), "Must define symbol name") + assert(defined(invoker.executable), "Must define executable") + + action(target_name) { + deps = invoker.deps + script = "//third_party/dart/runtime/tools/bin_to_coff.py" + output = invoker.input + ".o" + args = [ + "--input", + rebase_path(invoker.input), + "--output", + rebase_path(output), + "--symbol_name", + invoker.symbol, + ] + + if (defined(invoker.size_symbol)) { + args += [ + "--size_symbol_name", + invoker.size_symbol, + ] + } + + if (invoker.executable) { + args += [ "--executable" ] + } + + if (current_cpu == "x64") { + args += [ "--64-bit" ] + } + inputs = [ + invoker.input, + ] + outputs = [ + output, + ] + } +} + +template("bin_to_linkable") { + assert(defined(invoker.deps), "Must define deps") + assert(defined(invoker.input), "Must define input binary file") + assert(defined(invoker.symbol), "Must define symbol name") + target_type = "bin_to_assembly" + if (is_win) { + target_type = "bin_to_coff" + } + + target(target_type, target_name) { + forward_variables_from(invoker, "*") + } +} + +bin_to_linkable("vm_snapshot_data_linkable") { deps = [ ":generate_snapshot_bin", ] input = "$target_gen_dir/vm_isolate_snapshot.bin" - output = "$target_gen_dir/vm_snapshot_data.S" symbol = "kDartVmSnapshotData" executable = false } -bin_to_assembly("vm_snapshot_instructions_assembly") { +bin_to_linkable("vm_snapshot_instructions_linkable") { deps = [ ":generate_snapshot_bin", ] input = "$target_gen_dir/vm_snapshot_instructions.bin" - output = "$target_gen_dir/vm_snapshot_instructions.S" symbol = "kDartVmSnapshotInstructions" executable = true } -bin_to_assembly("isolate_snapshot_data_assembly") { +bin_to_linkable("isolate_snapshot_data_linkable") { deps = [ ":generate_snapshot_bin", ] input = "$target_gen_dir/isolate_snapshot.bin" - output = "$target_gen_dir/isolate_snapshot_data.S" symbol = "kDartIsolateSnapshotData" executable = false } -bin_to_assembly("isolate_snapshot_instructions_assembly") { +bin_to_linkable("isolate_snapshot_instructions_linkable") { deps = [ ":generate_snapshot_bin", ] input = "$target_gen_dir/isolate_snapshot_instructions.bin" - output = "$target_gen_dir/isolate_snapshot_instructions.S" symbol = "kDartIsolateSnapshotInstructions" executable = true } -source_set("snapshot") { +bin_to_linkable("platform_strong_dill_linkable") { deps = [ - ":isolate_snapshot_data_assembly", - ":isolate_snapshot_instructions_assembly", - ":vm_snapshot_data_assembly", - ":vm_snapshot_instructions_assembly", + ":kernel_platform_files", ] - sources = [ - "$target_gen_dir/isolate_snapshot_data.S", - "$target_gen_dir/isolate_snapshot_instructions.S", - "$target_gen_dir/vm_snapshot_data.S", - "$target_gen_dir/vm_snapshot_instructions.S", + if ((is_fuchsia || is_fuchsia_host) && !using_fuchsia_sdk) { + input = "$root_out_dir/flutter_runner_patched_sdk/platform_strong.dill" + } else { + input = "$root_out_dir/flutter_patched_sdk/platform_strong.dill" + } + symbol = "kPlatformStrongDill" + size_symbol = "kPlatformStrongDillSize" + executable = false +} + +source_set("snapshot") { + deps = [ + ":isolate_snapshot_data_linkable", + ":isolate_snapshot_instructions_linkable", + ":platform_strong_dill_linkable", + ":vm_snapshot_data_linkable", + ":vm_snapshot_instructions_linkable", ] + sources = get_target_outputs(":isolate_snapshot_data_linkable") + + get_target_outputs(":isolate_snapshot_instructions_linkable") + + get_target_outputs(":vm_snapshot_data_linkable") + + get_target_outputs(":vm_snapshot_instructions_linkable") + + get_target_outputs(":platform_strong_dill_linkable") } compile_platform("non_strong_platform") { single_root_scheme = "org-dartlang-sdk" single_root_base = rebase_path("../../../") - libraries_specification_uri = "org-dartlang-sdk:///flutter/lib/snapshot/libraries.json" + libraries_specification_uri = + "org-dartlang-sdk:///flutter/lib/snapshot/libraries.json" outputs = [ "$root_out_dir/flutter_patched_sdk/platform.dill", @@ -183,30 +252,35 @@ compile_platform("non_strong_platform") { compile_platform("strong_platform") { single_root_scheme = "org-dartlang-sdk" single_root_base = rebase_path("../../../") - libraries_specification_uri = "org-dartlang-sdk:///flutter/lib/snapshot/libraries.json" + libraries_specification_uri = + "org-dartlang-sdk:///flutter/lib/snapshot/libraries.json" outputs = [ "$root_out_dir/flutter_patched_sdk/platform_strong.dill", "$root_out_dir/flutter_patched_sdk/vm_outline_strong.dill", ] + is_runtime_mode_release = flutter_runtime_mode == "release" + allow_causal_async_stacks = !is_runtime_mode_release args = [ "--target=flutter", + "-Ddart.vm.product=$is_runtime_mode_release", + "-Ddart.developer.causal_async_stacks=$allow_causal_async_stacks", + "-Ddart.isVM=true", "dart:core", ] } # Fuchsia's snapshot requires a different platform with extra dart: libraries. -if (is_fuchsia || is_fuchsia_host) { +if ((is_fuchsia || is_fuchsia_host) && !using_fuchsia_sdk) { group("kernel_platform_files") { public_deps = [ - "//topaz/runtime/flutter_runner/kernel:kernel_platform_files" + "//topaz/runtime/flutter_runner/kernel:kernel_platform_files", ] } } else { group("kernel_platform_files") { public_deps = [ - ":non_strong_platform", ":strong_platform", ] } diff --git a/lib/snapshot/fuchsia_compilation_trace.txt b/lib/snapshot/fuchsia_compilation_trace.txt index 49bf715cfcdca..22337aa202081 100644 --- a/lib/snapshot/fuchsia_compilation_trace.txt +++ b/lib/snapshot/fuchsia_compilation_trace.txt @@ -1807,9 +1807,6 @@ dart:io,::,get:_OUTGOING_BUFFER_SIZE dart:io,::,_getHttpVersion dart:io,::,_setupHooks dart:io,::,_throwOnBadPort -dart:mozart.internal,Mozart,offerServiceProvider -dart:mozart.internal,Mozart,_offerServiceProvider -dart:mozart.internal,MozartStartupInfo,takeViewContainer dart:ui,TextBaseline,get:index dart:ui,StrokeCap,get:index dart:ui,BlurStyle,get:index diff --git a/lib/snapshot/libraries.json b/lib/snapshot/libraries.json index a59ae6c6624f6..99ef4cd778f8c 100644 --- a/lib/snapshot/libraries.json +++ b/lib/snapshot/libraries.json @@ -57,6 +57,14 @@ ], "uri": "../../../third_party/dart/sdk/lib/collection/collection.dart" }, + "ffi": { + "patches": [ + "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart", + "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart", + "../../../third_party/dart/runtime/lib/ffi_patch.dart" + ], + "uri": "../../../third_party/dart/sdk/lib/ffi/ffi.dart" + }, "typed_data": { "patches": "../../../third_party/dart/runtime/lib/typed_data_patch.dart", "uri": "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart" diff --git a/lib/snapshot/libraries.yaml b/lib/snapshot/libraries.yaml index 26c3277054c7d..c4244eaff8719 100644 --- a/lib/snapshot/libraries.yaml +++ b/lib/snapshot/libraries.yaml @@ -84,6 +84,13 @@ flutter: - "../../../third_party/dart/runtime/lib/profiler.dart" - "../../../third_party/dart/runtime/lib/timeline.dart" + ffi: + uri: "../../../third_party/dart/sdk/lib/ffi/ffi.dart" + patches: + - "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart" + - "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart" + - "../../../third_party/dart/runtime/lib/ffi_patch.dart" + _http: uri: "../../../third_party/dart/sdk/lib/_http/http.dart" diff --git a/lib/stub_ui/analysis_options.yaml b/lib/stub_ui/analysis_options.yaml new file mode 100644 index 0000000000000..6892f49dc726b --- /dev/null +++ b/lib/stub_ui/analysis_options.yaml @@ -0,0 +1 @@ +# Intentionally kept empty. \ No newline at end of file diff --git a/lib/stub_ui/lib/src/engine.dart b/lib/stub_ui/lib/src/engine.dart new file mode 100644 index 0000000000000..9c5a0760001fd --- /dev/null +++ b/lib/stub_ui/lib/src/engine.dart @@ -0,0 +1,143 @@ +// 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. + +library engine; + +import '../ui.dart' as ui; + +import 'dart:async'; +import 'dart:developer' as developer; +import 'dart:collection'; +import 'dart:convert' hide Codec; +import 'dart:html' as html; +import 'dart:js' as js; +import 'dart:js_util' as js_util; +import 'dart:math' as math; +import 'dart:typed_data'; + +import 'package:meta/meta.dart'; + +part 'engine/alarm_clock.dart'; +part 'engine/assets.dart'; +part 'engine/bitmap_canvas.dart'; +part 'engine/browser_detection.dart'; +part 'engine/compositor/engine_delegate.dart'; +part 'engine/compositor/layer.dart'; +part 'engine/compositor/layer_scene_builder.dart'; +part 'engine/compositor/layer_tree.dart'; +part 'engine/compositor/raster_cache.dart'; +part 'engine/compositor/rasterizer.dart'; +part 'engine/compositor/runtime_delegate.dart'; +part 'engine/compositor/surface.dart'; +part 'engine/compositor/viewport_metrics.dart'; +part 'engine/compositor/platform_message.dart'; +part 'engine/conic.dart'; +part 'engine/dom_canvas.dart'; +part 'engine/dom_renderer.dart'; +part 'engine/engine_canvas.dart'; +part 'engine/history.dart'; +part 'engine/houdini_canvas.dart'; +part 'engine/html_image_codec.dart'; +part 'engine/keyboard.dart'; +part 'engine/onscreen_logging.dart'; +part 'engine/path_to_svg.dart'; +part 'engine/pointer_binding.dart'; +part 'engine/recording_canvas.dart'; +part 'engine/semantics/checkable.dart'; +part 'engine/semantics/incrementable.dart'; +part 'engine/semantics/label_and_value.dart'; +part 'engine/semantics/scrollable.dart'; +part 'engine/semantics/semantics.dart'; +part 'engine/semantics/tappable.dart'; +part 'engine/semantics/text_field.dart'; +part 'engine/services/message_codec.dart'; +part 'engine/services/message_codecs.dart'; +part 'engine/shadow.dart'; +part 'engine/text/font_collection.dart'; +part 'engine/text/measurement.dart'; +part 'engine/text/ruler.dart'; +part 'engine/text/unicode_range.dart'; +part 'engine/text/word_break_properties.dart'; +part 'engine/text/word_breaker.dart'; +part 'engine/text_editing.dart'; +part 'engine/util.dart'; +part 'engine/validators.dart'; +part 'engine/vector_math.dart'; + +bool _engineInitialized = false; + +final List _hotRestartListeners = []; + +/// Requests that [listener] is called just before hot restarting the app. +void registerHotRestartListener(ui.VoidCallback listener) { + _hotRestartListeners.add(listener); +} + +/// This method performs one-time initialization of the Web environment that +/// supports the Flutter framework. +/// +/// This is only available on the Web, as native Flutter configures the +/// environment in the native embedder. +// TODO(yjbanov): we should refactor the code such that the framework does not +// call this method directly. +void webOnlyInitializeEngine() { + if (_engineInitialized) { + return; + } + + // Called by the Web runtime just before hot restarting the app. + // + // This extension cleans up resources that are registered with browser's + // global singletons that Dart compiler is unable to clean-up automatically. + // + // This extension does not need to clean-up Dart statics. Those are cleaned + // up by the compiler. + developer.registerExtension('ext.flutter.disassemble', (_, __) { + for (ui.VoidCallback listener in _hotRestartListeners) { + listener(); + } + return Future.value(developer.ServiceExtensionResponse.result('OK')); + }); + + _engineInitialized = true; + + // Calling this getter to force the DOM renderer to initialize before we + // initialize framework bindings. + domRenderer; + + bool waitingForAnimation = false; + ui.window.webOnlyScheduleFrameCallback = () { + // We're asked to schedule a frame and call `frameHandler` when the frame + // fires. + if (!waitingForAnimation) { + waitingForAnimation = true; + html.window.requestAnimationFrame((num highResTime) { + // Reset immediately, because `frameHandler` can schedule more frames. + waitingForAnimation = false; + + // We have to convert high-resolution time to `int` so we can construct + // a `Duration` out of it. However, high-res time is supplied in + // milliseconds as a double value, with sub-millisecond information + // hidden in the fraction. So we first multiply it by 1000 to uncover + // microsecond precision, and only then convert to `int`. + final highResTimeMicroseconds = (1000 * highResTime).toInt(); + + if (ui.window.onBeginFrame != null) { + ui.window.onBeginFrame( + new Duration(microseconds: highResTimeMicroseconds)); + } + + if (ui.window.onDrawFrame != null) { + // TODO(yjbanov): technically Flutter flushes microtasks between + // onBeginFrame and onDrawFrame. We don't, which hasn't + // been an issue yet, but eventually we'll have to + // implement it properly. + ui.window.onDrawFrame(); + } + }); + } + }; + + Keyboard.initialize(); +} diff --git a/lib/stub_ui/lib/src/engine/alarm_clock.dart b/lib/stub_ui/lib/src/engine/alarm_clock.dart new file mode 100644 index 0000000000000..5ed8288ef678d --- /dev/null +++ b/lib/stub_ui/lib/src/engine/alarm_clock.dart @@ -0,0 +1,110 @@ +// 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. + +part of engine; + +/// A function that returns current system time. +typedef TimestampFunction = DateTime Function(); + +/// Notifies the [callback] at the given [datetime]. +/// +/// Allows changing [datetime] in either direction before the alarm goes off. +/// +/// The implementation uses [Timer]s and therefore does not guarantee that it +/// will go off precisely at the specified time. For more details see: +/// +/// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Notes +class AlarmClock { + AlarmClock(TimestampFunction timestampFunction) + : _timestampFunction = timestampFunction; + + /// The function used to get current time. + final TimestampFunction _timestampFunction; + + /// The underlying timer used to schedule the callback. + Timer _timer; + + /// Current target time the [callback] is scheduled for. + DateTime _datetime; + + /// The callback called when the alarm goes off. + ui.VoidCallback callback; + + /// The time when the alarm clock will go off. + /// + /// If the time is in the past or is `null` the alarm clock will not go off. + /// + /// If the value is updated before an already scheduled timer goes off, the + /// previous time will not call the [callback]. Think of the updating this + /// value as "changing your mind" about when you want the next timer to fire. + DateTime get datetime => _datetime; + set datetime(DateTime value) { + if (value == _datetime) { + return; + } + + if (value == null) { + _cancelTimer(); + _datetime = null; + return; + } + + final DateTime now = _timestampFunction(); + + // We use the "not before" logic instead of "is after" because zero-duration + // timers are valid. + final bool isInTheFuture = !value.isBefore(now); + + if (!isInTheFuture) { + _cancelTimer(); + _datetime = value; + return; + } + + // At this point we have a non-null value that's in the future, and it is + // different from the current _datetime. We need to decide whether we need + // to create a new timer, or keep the existing one. + if (_timer == null) { + // We didn't have an existing timer, so create a new one. + _timer = Timer(value.difference(now), _timerDidFire); + } else { + assert(_datetime != null, + 'We can only have a timer if there is a non-null datetime'); + if (_datetime.isAfter(value)) { + // This is the case when the value moves the target time to an earlier + // point. Because there is no way to reconfigure an existing timer, we + // must cancel the old timer and schedule a new one. + _cancelTimer(); + _timer = Timer(value.difference(now), _timerDidFire); + } + // We don't need to do anything in the "else" branch. If the new value + // is in the future relative to the current datetime, the _timerDidFire + // will reschedule. + } + + _datetime = value; + } + + void _cancelTimer() { + if (_timer != null) { + _timer.cancel(); + _timer = null; + } + } + + void _timerDidFire() { + assert(_datetime != null, + 'If _datetime is null, the timer would have been cancelled'); + final DateTime now = _timestampFunction(); + // We use the "not before" logic instead of "is after" because we may have + // zero difference between now and _datetime. + if (!now.isBefore(_datetime)) { + _timer = null; + callback(); + } else { + // The timer fired before the target date. We need to reschedule. + _timer = Timer(_datetime.difference(now), _timerDidFire); + } + } +} diff --git a/lib/stub_ui/lib/src/engine/assets.dart b/lib/stub_ui/lib/src/engine/assets.dart new file mode 100644 index 0000000000000..50b56cdf0bf95 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/assets.dart @@ -0,0 +1,63 @@ +// 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. + +part of engine; + +/// This class downloads assets over the network. +/// +/// The assets are resolved relative to [assetsDir]. +class AssetManager { + static const String _defaultAssetsDir = 'assets'; + + /// The directory containing the assets. + final String assetsDir; + + const AssetManager({this.assetsDir = _defaultAssetsDir}); + + String getAssetUrl(String asset) { + var assetUri = Uri.parse(asset); + + String url; + + if (assetUri.hasScheme) { + url = asset; + } else { + url = '$assetsDir/$asset'; + } + + return url; + } + + Future load(String asset) async { + var url = getAssetUrl(asset); + try { + var request = + await html.HttpRequest.request(url, responseType: 'arraybuffer'); + + return (request.response as ByteBuffer).asByteData(); + } on html.ProgressEvent catch (e) { + final target = e.target; + if (target is html.HttpRequest) { + if (target.status == 404 && asset == 'AssetManifest.json') { + html.window.console + .warn('Asset manifest does not exist at `$url` – ignoring.'); + return Uint8List.fromList(utf8.encode('{}')).buffer.asByteData(); + } + throw AssetManagerException(url, target.status); + } + + rethrow; + } + } +} + +class AssetManagerException implements Exception { + final String url; + final int httpStatus; + + AssetManagerException(this.url, this.httpStatus); + + @override + String toString() => 'Failed to load asset at "$url" ($httpStatus)'; +} diff --git a/lib/stub_ui/lib/src/engine/bitmap_canvas.dart b/lib/stub_ui/lib/src/engine/bitmap_canvas.dart new file mode 100644 index 0000000000000..fd2acef194cbf --- /dev/null +++ b/lib/stub_ui/lib/src/engine/bitmap_canvas.dart @@ -0,0 +1,1093 @@ +// 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. + +part of engine; + +/// A raw HTML canvas that is directly written to. +class BitmapCanvas extends EngineCanvas with SaveStackTracking { + /// The rectangle positioned relative to the parent layer's coordinate + /// system's origin, within which this canvas paints. + /// + /// Painting outside these bounds will result in cropping. + ui.Rect bounds; + + /// The amount of padding to add around the edges of this canvas to + /// ensure that anti-aliased arcs are not clipped. + static const paddingPixels = 1; + + final html.Element rootElement = new html.Element.tag('flt-canvas'); + html.CanvasElement _canvas; + html.CanvasRenderingContext2D _ctx; + + /// The size of the paint [bounds]. + ui.Size get size => bounds.size; + + /// The last paragraph style is cached to optimize the case where the style + /// hasn't changed. + ParagraphGeometricStyle _cachedLastStyle; + + /// List of extra sibling elements created for paragraphs and clipping. + final _children = new List(); + + /// The number of pixels along the width of the bitmap that the canvas element + /// renders into. + /// + /// These pixels are different from the logical CSS pixels. Here a pixel + /// literally means 1 point with a RGBA color. + int get widthInBitmapPixels => _widthInBitmapPixels; + int _widthInBitmapPixels; + + /// The number of pixels along the width of the bitmap that the canvas element + /// renders into. + /// + /// These pixels are different from the logical CSS pixels. Here a pixel + /// literally means 1 point with a RGBA color. + int get heightInBitmapPixels => _heightInBitmapPixels; + int _heightInBitmapPixels; + + /// The number of pixels in the bitmap that the canvas element renders into. + /// + /// These pixels are different from the logical CSS pixels. Here a pixel + /// literally means 1 point with a RGBA color. + int get bitmapPixelCount => widthInBitmapPixels * heightInBitmapPixels; + + int _saveCount = 0; + + /// Keeps track of what device pixel ratio was used when this [BitmapCanvas] + /// was created. + final double _devicePixelRatio = html.window.devicePixelRatio; + + // Cached current filter, fill and stroke style to reduce updates to + // CanvasRenderingContext2D that are slow even when resetting to null. + String _prevFilter = 'none'; + Object _prevFillStyle = null; + Object _prevStrokeStyle = null; + + /// Allocates a canvas with enough memory to paint a picture within the given + /// [bounds]. + /// + /// This canvas can be reused by pictures with different paint bounds as long + /// as the [Rect.size] of the bounds fully fit within the size used to + /// initialize this canvas. + BitmapCanvas(this.bounds) { + rootElement.style.position = 'absolute'; + + // Adds one extra pixel to the requested size. This is to compensate for + // _initializeViewport() snapping canvas position to 1 pixel, causing + // painting to overflow by at most 1 pixel. + final double boundsWidth = size.width + 1 + 2 * paddingPixels; + final double boundsHeight = size.height + 1 + 2 * paddingPixels; + _widthInBitmapPixels = (boundsWidth * html.window.devicePixelRatio).ceil(); + _heightInBitmapPixels = + (boundsHeight * html.window.devicePixelRatio).ceil(); + + // Compute the final CSS canvas size given the actual pixel count we + // allocated. This is done for the following reasons: + // + // * To satisfy the invariant: pixel size = css size * device pixel ratio. + // * To make sure that when we scale the canvas by devicePixelRatio (see + // _initializeViewport below) the pixels line up. + final double cssWidth = _widthInBitmapPixels / html.window.devicePixelRatio; + final double cssHeight = + _heightInBitmapPixels / html.window.devicePixelRatio; + + _canvas = new html.CanvasElement( + width: _widthInBitmapPixels, + height: _heightInBitmapPixels, + ); + _canvas.style + ..position = 'absolute' + ..width = '${cssWidth}px' + ..height = '${cssHeight}px'; + _ctx = _canvas.context2D; + rootElement.append(_canvas); + _initializeViewport(); + } + + @override + void dispose() { + super.dispose(); + // Webkit has a threshold for the amount of canvas pixels an app can + // allocate. Even though our canvases are being garbage-collected as + // expected when we don't need them, Webkit keeps track of their sizes + // towards the threshold. Setting width and height to zero tricks Webkit + // into thinking that this canvas has a zero size so it doesn't count it + // towards the threshold. + if (browserEngine == BrowserEngine.webkit) { + _canvas.width = _canvas.height = 0; + } + } + + /// Prepare to reuse this canvas by clearing it's current contents. + @override + void clear() { + super.clear(); + for (int i = 0, len = _children.length; i < len; i++) { + _children[i].remove(); + } + _children.clear(); + _cachedLastStyle = null; + // Restore to the state where we have only applied the scaling. + if (_ctx != null) { + _ctx.restore(); + _ctx.clearRect(0, 0, _widthInBitmapPixels, _heightInBitmapPixels); + _ctx.font = ''; + _initializeViewport(); + } + if (_canvas != null) { + _canvas.style.transformOrigin = ''; + _canvas.style.transform = ''; + } + } + + /// Checks whether this [BitmapCanvas] can still be recycled and reused. + /// + /// See also: + /// + /// * [PersistedStandardPicture._applyBitmapPaint] which uses this method to + /// decide whether to reuse this canvas or not. + /// * [PersistedStandardPicture._recycleCanvas] which also uses this method + /// for the same reason. + bool isReusable() { + return _devicePixelRatio == html.window.devicePixelRatio; + } + + /// Configures the canvas such that its coordinate system follows the scene's + /// coordinate system, and the pixel ratio is applied such that CSS pixels are + /// translated to bitmap pixels. + void _initializeViewport() { + // Save the canvas state with top-level transforms so we can undo + // any clips later when we reuse the canvas. + _ctx.save(); + + // We always start with identity transform because the surrounding transform + // is applied on the DOM elements. + _ctx.setTransform(1, 0, 0, 1, 0, 0); + + // This scale makes sure that 1 CSS pixel is translated to the correct + // number of bitmap pixels. + _ctx.scale(html.window.devicePixelRatio, html.window.devicePixelRatio); + + // Flutter emits paint operations positioned relative to the parent layer's + // coordinate system. However, canvas' coordinate system's origin is always + // in the top-left corner of the canvas. We therefore need to inject an + // initial translation so the paint operations are positioned as expected. + + // The flooring of the value is to ensure that canvas' top-left corner + // lands on the physical pixel. + final int canvasPositionX = bounds.left.floor() - paddingPixels; + final int canvasPositionY = bounds.top.floor() - paddingPixels; + final double canvasPositionCorrectionX = + bounds.left - paddingPixels - canvasPositionX.toDouble(); + final double canvasPositionCorrectionY = + bounds.top - paddingPixels - canvasPositionY.toDouble(); + + rootElement.style.transform = + 'translate(${canvasPositionX}px, ${canvasPositionY}px)'; + + // This compensates for the translate on the `rootElement`. + translate( + -bounds.left + canvasPositionCorrectionX + paddingPixels, + -bounds.top + canvasPositionCorrectionY + paddingPixels, + ); + } + + /// The `` element used by this bitmap canvas. + html.CanvasElement get canvas => _canvas; + + /// The 2D context of the `` element used by this bitmap canvas. + html.CanvasRenderingContext2D get ctx => _ctx; + + /// Sets the global paint styles to correspond to [paint]. + void _applyPaint(ui.PaintData paint) { + ctx.globalCompositeOperation = + _stringForBlendMode(paint.blendMode) ?? 'source-over'; + ctx.lineWidth = paint.strokeWidth ?? 1.0; + var cap = paint.strokeCap; + if (cap != null) { + ctx.lineCap = _stringForStrokeCap(cap); + } else { + ctx.lineCap = 'butt'; + } + var join = paint.strokeJoin; + if (join != null) { + ctx.lineJoin = _stringForStrokeJoin(join); + } else { + ctx.lineJoin = 'miter'; + } + if (paint.shader != null) { + var paintStyle = paint.shader.createPaintStyle(ctx); + _setFillAndStrokeStyle(paintStyle, paintStyle); + } else if (paint.color != null) { + var colorString = paint.color.toCssString(); + _setFillAndStrokeStyle(colorString, colorString); + } + if (paint.maskFilter != null) { + _setFilter('blur(${paint.maskFilter.webOnlySigma}px)'); + } + } + + void _strokeOrFill(ui.PaintData paint, {bool resetPaint = true}) { + switch (paint.style) { + case ui.PaintingStyle.stroke: + ctx.stroke(); + break; + case ui.PaintingStyle.fill: + default: + ctx.fill(); + break; + } + if (resetPaint) { + _resetPaint(); + } + } + + /// Resets the paint styles that were set due to a previous paint command. + /// + /// For example, if a previous paint commands has a blur filter, we need to + /// undo that filter here. + /// + /// This needs to be called after [_applyPaint]. + void _resetPaint() { + _setFilter('none'); + _setFillAndStrokeStyle(null, null); + } + + void _setFilter(String value) { + if (_prevFilter != value) { + _prevFilter = ctx.filter = value; + } + } + + void _setFillAndStrokeStyle(Object fillStyle, Object strokeStyle) { + final _ctx = ctx; + if (!identical(_prevFillStyle, fillStyle)) { + _prevFillStyle = _ctx.fillStyle = fillStyle; + } + if (!identical(_prevStrokeStyle, strokeStyle)) { + _prevStrokeStyle = _ctx.strokeStyle = strokeStyle; + } + } + + @override + int save() { + super.save(); + ctx.save(); + return _saveCount++; + } + + void saveLayer(ui.Rect bounds, _) { + save(); + } + + @override + void restore() { + super.restore(); + ctx.restore(); + _saveCount--; + _cachedLastStyle = null; + } + + // TODO(yjbanov): not sure what this is attempting to do, but it is probably + // wrong because some clips and transforms are expressed using + // HTML DOM elements. + void restoreToCount(int count) { + assert(_saveCount >= count); + int restores = _saveCount - count; + for (int i = 0; i < restores; i++) { + ctx.restore(); + } + _saveCount = count; + } + + @override + void translate(double dx, double dy) { + super.translate(dx, dy); + ctx.translate(dx, dy); + } + + @override + void scale(double sx, double sy) { + super.scale(sx, sy); + ctx.scale(sx, sy); + } + + @override + void rotate(double radians) { + super.rotate(radians); + ctx.rotate(radians); + } + + @override + void skew(double sx, double sy) { + super.skew(sx, sy); + ctx.transform(1, sy, sx, 1, 0, 0); + // | | | | | | + // | | | | | f - vertical translation + // | | | | e - horizontal translation + // | | | d - vertical scaling + // | | c - horizontal skewing + // | b - vertical skewing + // a - horizontal scaling + // + // Source: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/transform + } + + @override + void transform(Float64List matrix4) { + super.transform(matrix4); + + // Canvas2D transform API: + // + // ctx.transform(a, b, c, d, e, f); + // + // In 3x3 matrix form assuming vector representation of (x, y, 1): + // + // a c e + // b d f + // 0 0 1 + // + // This translates to 4x4 matrix with vector representation of (x, y, z, 1) + // as: + // + // a c 0 e + // b d 0 f + // 0 0 1 0 + // 0 0 0 1 + // + // This matrix is sufficient to represent 2D rotates, translates, scales, + // and skews. + assert(() { + if (matrix4[2] != 0.0 || + matrix4[3] != 0.0 || + matrix4[7] != 0.0 || + matrix4[8] != 0.0 || + matrix4[9] != 0.0 || + matrix4[10] != 1.0 || + matrix4[11] != 0.0 || + matrix4[14] != 0.0 || + matrix4[15] != 1.0) { + print('WARNING: 3D transformation matrix was passed to BitmapCanvas.'); + } + return true; + }()); + _ctx.transform( + matrix4[0], + matrix4[1], + matrix4[4], + matrix4[5], + matrix4[12], + matrix4[13], + ); + } + + @override + void clipRect(ui.Rect rect) { + super.clipRect(rect); + ctx.beginPath(); + ctx.rect(rect.left, rect.top, rect.width, rect.height); + ctx.clip(); + } + + @override + void clipRRect(ui.RRect rrect) { + super.clipRRect(rrect); + var path = new ui.Path()..addRRect(rrect); + _runPath(path); + ctx.clip(); + } + + @override + void clipPath(ui.Path path) { + super.clipPath(path); + _runPath(path); + ctx.clip(); + } + + @override + void drawColor(ui.Color color, ui.BlendMode blendMode) { + ctx.globalCompositeOperation = _stringForBlendMode(blendMode); + + // Fill a virtually infinite rect with the color. + // + // We can't use (0, 0, width, height) because the current transform can + // cause it to not fill the entire clip. + ctx.fillRect(-10000, -10000, 20000, 20000); + } + + @override + void drawLine(ui.Offset p1, ui.Offset p2, ui.PaintData paint) { + _applyPaint(paint); + ctx.beginPath(); + ctx.moveTo(p1.dx, p1.dy); + ctx.lineTo(p2.dx, p2.dy); + ctx.stroke(); + _resetPaint(); + } + + @override + void drawPaint(ui.PaintData paint) { + _applyPaint(paint); + ctx.beginPath(); + + // Fill a virtually infinite rect with the color. + // + // We can't use (0, 0, width, height) because the current transform can + // cause it to not fill the entire clip. + ctx.fillRect(-10000, -10000, 20000, 20000); + _resetPaint(); + } + + @override + void drawRect(ui.Rect rect, ui.PaintData paint) { + _applyPaint(paint); + ctx.beginPath(); + ctx.rect(rect.left, rect.top, rect.width, rect.height); + _strokeOrFill(paint); + } + + @override + void drawRRect(ui.RRect rrect, ui.PaintData paint) { + _applyPaint(paint); + _drawRRectPath(rrect); + _strokeOrFill(paint); + } + + void _drawRRectPath(ui.RRect rrect, {bool startNewPath = true}) { + // TODO(mdebbar): there's a bug in this code, it doesn't correctly handle + // the case when the radius is greater than the width of the + // rect. When we fix that in houdini_painter.js, we need to + // fix it here too. + // To draw the rounded rectangle, perform the following 8 steps: + // 1. Flip left,right top,bottom since web doesn't support flipped + // coordinates with negative radii. + // 2. draw the line for the top + // 3. draw the arc for the top-right corner + // 4. draw the line for the right side + // 5. draw the arc for the bottom-right corner + // 6. draw the line for the bottom of the rectangle + // 7. draw the arc for the bottom-left corner + // 8. draw the line for the left side + // 9. draw the arc for the top-left corner + // + // After drawing, the current point will be the left side of the top of the + // rounded rectangle (after the corner). + // TODO(het): Confirm that this is the end point in Flutter for RRect + + var left = rrect.left; + var right = rrect.right; + var top = rrect.top; + var bottom = rrect.bottom; + if (left > right) { + left = right; + right = rrect.left; + } + if (top > bottom) { + top = bottom; + bottom = rrect.top; + } + var trRadiusX = rrect.trRadiusX.abs(); + var tlRadiusX = rrect.tlRadiusX.abs(); + var trRadiusY = rrect.trRadiusY.abs(); + var tlRadiusY = rrect.tlRadiusY.abs(); + var blRadiusX = rrect.blRadiusX.abs(); + var brRadiusX = rrect.brRadiusX.abs(); + var blRadiusY = rrect.blRadiusY.abs(); + var brRadiusY = rrect.brRadiusY.abs(); + + ctx.moveTo(left + trRadiusX, top); + + if (startNewPath) { + ctx.beginPath(); + } + + // Top side and top-right corner + ctx.lineTo(right - trRadiusX, top); + ctx.ellipse( + right - trRadiusX, + top + trRadiusY, + trRadiusX, + trRadiusY, + 0, + 1.5 * math.pi, + 2.0 * math.pi, + false, + ); + + // Right side and bottom-right corner + ctx.lineTo(right, bottom - brRadiusY); + ctx.ellipse( + right - brRadiusX, + bottom - brRadiusY, + brRadiusX, + brRadiusY, + 0, + 0, + 0.5 * math.pi, + false, + ); + + // Bottom side and bottom-left corner + ctx.lineTo(left + blRadiusX, bottom); + ctx.ellipse( + left + blRadiusX, + bottom - blRadiusY, + blRadiusX, + blRadiusY, + 0, + 0.5 * math.pi, + math.pi, + false, + ); + + // Left side and top-left corner + ctx.lineTo(left, top + tlRadiusY); + ctx.ellipse( + left + tlRadiusX, + top + tlRadiusY, + tlRadiusX, + tlRadiusY, + 0, + math.pi, + 1.5 * math.pi, + false, + ); + } + + void _drawRRectPathReverse(ui.RRect rrect, {bool startNewPath = true}) { + var left = rrect.left; + var right = rrect.right; + var top = rrect.top; + var bottom = rrect.bottom; + var trRadiusX = rrect.trRadiusX.abs(); + var tlRadiusX = rrect.tlRadiusX.abs(); + var trRadiusY = rrect.trRadiusY.abs(); + var tlRadiusY = rrect.tlRadiusY.abs(); + var blRadiusX = rrect.blRadiusX.abs(); + var brRadiusX = rrect.brRadiusX.abs(); + var blRadiusY = rrect.blRadiusY.abs(); + var brRadiusY = rrect.brRadiusY.abs(); + + if (left > right) { + left = right; + right = rrect.left; + } + if (top > bottom) { + top = bottom; + bottom = rrect.top; + } + // Draw the rounded rectangle, counterclockwise. + ctx.moveTo(right - trRadiusX, top); + + if (startNewPath) { + ctx.beginPath(); + } + + // Top side and top-left corner + ctx.lineTo(left + tlRadiusX, top); + ctx.ellipse( + left + tlRadiusX, + top + tlRadiusY, + tlRadiusX, + tlRadiusY, + 0, + 1.5 * math.pi, + 1 * math.pi, + true, + ); + + // Left side and bottom-left corner + ctx.lineTo(left, bottom - blRadiusY); + ctx.ellipse( + left + blRadiusX, + bottom - blRadiusY, + blRadiusX, + blRadiusY, + 0, + 1 * math.pi, + 0.5 * math.pi, + true, + ); + + // Bottom side and bottom-right corner + ctx.lineTo(right - brRadiusX, bottom); + ctx.ellipse( + right - brRadiusX, + bottom - brRadiusY, + brRadiusX, + brRadiusY, + 0, + 0.5 * math.pi, + 0 * math.pi, + true, + ); + + // Right side and top-right corner + ctx.lineTo(right, top + trRadiusY); + ctx.ellipse( + right - trRadiusX, + top + trRadiusY, + trRadiusX, + trRadiusY, + 0, + 0 * math.pi, + 1.5 * math.pi, + true, + ); + } + + @override + void drawDRRect(ui.RRect outer, ui.RRect inner, ui.PaintData paint) { + _applyPaint(paint); + _drawRRectPath(outer); + _drawRRectPathReverse(inner, startNewPath: false); + _strokeOrFill(paint); + } + + @override + void drawOval(ui.Rect rect, ui.PaintData paint) { + _applyPaint(paint); + ctx.beginPath(); + ctx.ellipse(rect.center.dx, rect.center.dy, rect.width / 2, rect.height / 2, + 0, 0, 2.0 * math.pi, false); + _strokeOrFill(paint); + } + + @override + void drawCircle(ui.Offset c, double radius, ui.PaintData paint) { + _applyPaint(paint); + ctx.beginPath(); + ctx.ellipse(c.dx, c.dy, radius, radius, 0, 0, 2.0 * math.pi, false); + _strokeOrFill(paint); + } + + @override + void drawPath(ui.Path path, ui.PaintData paint) { + _applyPaint(paint); + _runPath(path); + _strokeOrFill(paint); + } + + @override + void drawShadow(ui.Path path, ui.Color color, double elevation, + bool transparentOccluder) { + final shadows = ElevationShadow.computeCanvasShadows(elevation, color); + if (shadows.isNotEmpty) { + for (final shadow in shadows) { + // TODO(het): Shadows with transparent occluders are not supported + // on webkit since filter is unsupported. + if (transparentOccluder && browserEngine != BrowserEngine.webkit) { + // We paint shadows using a path and a mask filter instead of the + // built-in shadow* properties. This is because the color alpha of the + // paint is added to the shadow. The effect we're looking for is to just + // paint the shadow without the path itself, but if we use a non-zero + // alpha for the paint the path is painted in addition to the shadow, + // which is undesirable. + final paint = ui.Paint() + ..color = shadow.color + ..style = ui.PaintingStyle.fill + ..strokeWidth = 0.0 + ..maskFilter = ui.MaskFilter.blur(ui.BlurStyle.normal, shadow.blur); + _ctx.save(); + _ctx.translate(shadow.offsetX, shadow.offsetY); + final paintData = paint.webOnlyPaintData; + _applyPaint(paintData); + _runPath(path); + _strokeOrFill(paintData, resetPaint: false); + _ctx.restore(); + } else { + // TODO(het): We fill the path with this paint, then later we clip + // by the same path and fill it with a fully opaque color (we know + // the color is fully opaque because `transparentOccluder` is false. + // However, due to anti-aliasing of the clip, a few pixels of the + // path we are about to paint may still be visible after we fill with + // the opaque occluder. For that reason, we fill with the shadow color, + // and set the shadow color to fully opaque. This way, the visible + // pixels are less opaque and less noticeable. + final paint = ui.Paint() + ..color = shadow.color + ..style = ui.PaintingStyle.fill + ..strokeWidth = 0.0; + _ctx.save(); + final paintData = paint.webOnlyPaintData; + _applyPaint(paintData); + _ctx.shadowBlur = shadow.blur; + _ctx.shadowColor = shadow.color.withAlpha(0xff).toCssString(); + _ctx.shadowOffsetX = shadow.offsetX; + _ctx.shadowOffsetY = shadow.offsetY; + _runPath(path); + _strokeOrFill(paintData, resetPaint: false); + _ctx.restore(); + } + } + _resetPaint(); + } + } + + @override + void drawImage(ui.Image image, ui.Offset p, ui.PaintData paint) { + _applyPaint(paint); + html.Element imgElement = (image as HtmlImage).imgElement.clone(true); + imgElement.style + ..position = 'absolute' + ..transform = 'translate(${p.dx}px, ${p.dy}px)'; + rootElement.append(imgElement); + } + + @override + void drawImageRect( + ui.Image image, ui.Rect src, ui.Rect dst, ui.PaintData paint) { + // TODO(het): Check if the src rect is the entire image, and if so just + // append the imgElement and set it's height and width. + ctx.drawImageScaledFromSource( + (image as HtmlImage).imgElement, + src.left, + src.top, + src.width, + src.height, + dst.left, + dst.top, + dst.width, + dst.height, + ); + } + + @override + void drawParagraph(ui.Paragraph paragraph, ui.Offset offset) { + assert(paragraph.webOnlyIsLaidOut); + + final ParagraphGeometricStyle style = + paragraph.webOnlyGetParagraphGeometricStyle(); + + if (paragraph.webOnlyDrawOnCanvas) { + if (style != _cachedLastStyle) { + ctx.font = style.cssFontString; + _cachedLastStyle = style; + } + _applyPaint(paragraph.webOnlyGetPaint().webOnlyPaintData); + ctx.fillText( + paragraph.webOnlyGetPlainText(), + offset.dx + paragraph.webOnlyAlignOffset, + offset.dy + paragraph.alphabeticBaseline); + _resetPaint(); + return; + } + + // This will cause a new canvas to be created for the next painting + // operation. This ensures that shapes that appear on top of text are + // rendered correctly. + // TODO(yjbanov): as our sample apps show it is a very common case for text + // drawing operations to interleave non-text operations, + // which generates a lot of HTML canvases for a single + // Flutter Picture. This kills performance. We need a smarter + // strategy, such as deducing painting bounds from paint ops + // and/or sinking non-intersecting graphics down the canvas + // chain. + // _canvas = null; + + html.Element paragraphElement = + paragraph.webOnlyGetParagraphElement().clone(true); + + final html.CssStyleDeclaration paragraphStyle = paragraphElement.style; + paragraphStyle + ..position = 'absolute' + ..whiteSpace = 'pre-wrap' + ..width = '${paragraph.width}px'; + + // TODO(flutter_web): Implement the ellipsis overflow for multi-line text + // too. As a pre-requisite, we need to be able to programmatically find + // line breaks. + if (style.ellipsis != null && + (style.maxLines == null || style.maxLines == 1)) { + paragraphStyle + ..height = '${paragraph.webOnlyMaxLinesHeight}px' + ..whiteSpace = 'pre' + ..overflow = 'hidden' + ..textOverflow = 'ellipsis'; + } else if (paragraph.didExceedMaxLines) { + paragraphStyle + ..height = '${paragraph.webOnlyMaxLinesHeight}px' + ..overflowY = 'hidden'; + } else { + paragraphStyle.height = '${paragraph.height}px'; + } + + if (isClipped) { + List clipElements = + _clipContent(_clipStack, paragraphElement, offset, currentTransform); + for (html.Element clipElement in clipElements) { + rootElement.append(clipElement); + _children.add(clipElement); + } + } else { + String cssTransform = + matrix4ToCssTransform(transformWithOffset(currentTransform, offset)); + paragraphStyle.transform = cssTransform; + rootElement.append(paragraphElement); + } + _children.add(paragraphElement); + } + + /// Paints the [picture] into this canvas. + void drawPicture(ui.Picture picture) { + picture.recordingCanvas.apply(this); + } + + /// 'Runs' the given [path] by applying all of its commands to the canvas. + void _runPath(ui.Path path) { + ctx.beginPath(); + for (var subpath in path.subpaths) { + for (var command in subpath.commands) { + switch (command.type) { + case PathCommandTypes.bezierCurveTo: + BezierCurveTo curve = command; + ctx.bezierCurveTo( + curve.x1, curve.y1, curve.x2, curve.y2, curve.x3, curve.y3); + break; + case PathCommandTypes.close: + ctx.closePath(); + break; + case PathCommandTypes.ellipse: + Ellipse ellipse = command; + ctx.ellipse( + ellipse.x, + ellipse.y, + ellipse.radiusX, + ellipse.radiusY, + ellipse.rotation, + ellipse.startAngle, + ellipse.endAngle, + ellipse.anticlockwise); + break; + case PathCommandTypes.lineTo: + LineTo lineTo = command; + ctx.lineTo(lineTo.x, lineTo.y); + break; + case PathCommandTypes.moveTo: + MoveTo moveTo = command; + ctx.moveTo(moveTo.x, moveTo.y); + break; + case PathCommandTypes.rRect: + RRectCommand rrectCommand = command; + _drawRRectPath(rrectCommand.rrect, startNewPath: false); + break; + case PathCommandTypes.rect: + RectCommand rectCommand = command; + ctx.rect(rectCommand.x, rectCommand.y, rectCommand.width, + rectCommand.height); + break; + case PathCommandTypes.quadraticCurveTo: + QuadraticCurveTo quadraticCurveTo = command; + ctx.quadraticCurveTo(quadraticCurveTo.x1, quadraticCurveTo.y1, + quadraticCurveTo.x2, quadraticCurveTo.y2); + break; + default: + throw new UnimplementedError('Unknown path command $command'); + } + } + } + } +} + +String _stringForBlendMode(ui.BlendMode blendMode) { + if (blendMode == null) return null; + switch (blendMode) { + case ui.BlendMode.srcOver: + return 'source-over'; + case ui.BlendMode.srcIn: + return 'source-in'; + case ui.BlendMode.srcOut: + return 'source-out'; + case ui.BlendMode.srcATop: + return 'source-atop'; + case ui.BlendMode.dstOver: + return 'destination-over'; + case ui.BlendMode.dstIn: + return 'destination-in'; + case ui.BlendMode.dstOut: + return 'destination-out'; + case ui.BlendMode.dstATop: + return 'destination-atop'; + case ui.BlendMode.plus: + return 'lighten'; + case ui.BlendMode.src: + return 'copy'; + case ui.BlendMode.xor: + return 'xor'; + case ui.BlendMode.multiply: + // Falling back to multiply, ignoring alpha channel. + // TODO(flutter_web): only used for debug, find better fallback for web. + case ui.BlendMode.modulate: + return 'multiply'; + case ui.BlendMode.screen: + return 'screen'; + case ui.BlendMode.overlay: + return 'overlay'; + case ui.BlendMode.darken: + return 'darken'; + case ui.BlendMode.lighten: + return 'lighten'; + case ui.BlendMode.colorDodge: + return 'color-dodge'; + case ui.BlendMode.colorBurn: + return 'color-burn'; + case ui.BlendMode.hardLight: + return 'hard-light'; + case ui.BlendMode.softLight: + return 'soft-light'; + case ui.BlendMode.difference: + return 'difference'; + case ui.BlendMode.exclusion: + return 'exclusion'; + case ui.BlendMode.hue: + return 'hue'; + case ui.BlendMode.saturation: + return 'saturation'; + case ui.BlendMode.color: + return 'color'; + case ui.BlendMode.luminosity: + return 'luminosity'; + default: + throw new UnimplementedError( + 'Flutter Web does not support the blend mode: $blendMode'); + } +} + +String _stringForStrokeCap(ui.StrokeCap strokeCap) { + if (strokeCap == null) return null; + switch (strokeCap) { + case ui.StrokeCap.butt: + return 'butt'; + case ui.StrokeCap.round: + return 'round'; + case ui.StrokeCap.square: + default: + return 'square'; + } +} + +String _stringForStrokeJoin(ui.StrokeJoin strokeJoin) { + assert(strokeJoin != null); + switch (strokeJoin) { + case ui.StrokeJoin.round: + return 'round'; + case ui.StrokeJoin.bevel: + return 'bevel'; + case ui.StrokeJoin.miter: + default: + return 'miter'; + } +} + +/// Clips the content element against a stack of clip operations and returns +/// root of a tree that contains content node. +/// +/// The stack of clipping rectangles generate an element that either uses +/// overflow:hidden with bounds to clip child or sets a clip-path to clip +/// it's contents. The clipping rectangles are nested and returned together +/// with a list of svg elements that provide clip-paths. +List _clipContent(List<_SaveClipEntry> clipStack, + html.HtmlElement content, ui.Offset offset, Matrix4 currentTransform) { + html.Element root, curElement; + List clipDefs = []; + for (int clipIndex = 0, len = clipStack.length; + clipIndex < len; + clipIndex++) { + final _SaveClipEntry entry = clipStack[clipIndex]; + html.HtmlElement newElement = new html.DivElement(); + if (root == null) { + root = newElement; + } else { + domRenderer.append(curElement, newElement); + } + curElement = newElement; + ui.Rect rect = entry.rect; + var newClipTransform = entry.currentTransform; + if (rect != null) { + final clipOffsetX = rect.left; + final clipOffsetY = rect.top; + newClipTransform = newClipTransform.clone() + ..translate(clipOffsetX, clipOffsetY); + curElement.style + ..overflow = 'hidden' + ..transform = matrix4ToCssTransform(newClipTransform) + ..transformOrigin = '0 0 0' + ..width = '${rect.right - clipOffsetX}px' + ..height = '${rect.bottom - clipOffsetY}px'; + } else if (entry.rrect != null) { + ui.RRect roundRect = entry.rrect; + final borderRadius = '${roundRect.tlRadiusX}px ${roundRect.trRadiusX}px ' + '${roundRect.brRadiusX}px ${roundRect.blRadiusX}px'; + final clipOffsetX = roundRect.left; + final clipOffsetY = roundRect.top; + newClipTransform = newClipTransform.clone() + ..translate(clipOffsetX, clipOffsetY); + curElement.style + ..borderRadius = borderRadius + ..overflow = 'hidden' + ..transform = matrix4ToCssTransform(newClipTransform) + ..transformOrigin = '0 0 0' + ..width = '${roundRect.right - clipOffsetX}px' + ..height = '${roundRect.bottom - clipOffsetY}px'; + } else if (entry.path != null) { + curElement.style.transform = matrix4ToCssTransform(newClipTransform); + String svgClipPath = _pathToSvgClipPath(entry.path); + html.Element clipElement = + html.Element.html(svgClipPath, treeSanitizer: _NullTreeSanitizer()); + domRenderer.setElementStyle( + curElement, 'clip-path', 'url(#svgClipText${_clipTextCounter})'); + domRenderer.setElementStyle(curElement, '-webkit-clip-path', + 'url(#svgClipText${_clipTextCounter})'); + clipDefs.add(clipElement); + } + // Reverse the transform of the clipping element so children can use + // effective transform to render. + // TODO(flutter_web): When we have more than a single clip element, + // reduce number of div nodes by merging (multiplying transforms). + var reverseTransformDiv = new html.DivElement(); + reverseTransformDiv.style + ..transform = + _cssTransformAtOffset(newClipTransform.clone()..invert(), 0, 0) + ..transformOrigin = '0 0 0'; + curElement.append(reverseTransformDiv); + curElement = reverseTransformDiv; + } + + root.style.position = 'absolute'; + domRenderer.append(curElement, content); + content.style.transform = + _cssTransformAtOffset(currentTransform, offset.dx, offset.dy); + return [root]..addAll(clipDefs); +} + +String _cssTransformAtOffset( + Matrix4 transform, double offsetX, double offsetY) { + return matrix4ToCssTransform( + transformWithOffset(transform, ui.Offset(offsetX, offsetY))); +} + +class _NullTreeSanitizer implements html.NodeTreeSanitizer { + void sanitizeTree(html.Node node) {} +} + +int _clipTextCounter = 0; + +/// Converts Path to svg element that contains a clip-path definition. +/// TODO(flutter_web): unify with version used in compositing.dart. +String _pathToSvgClipPath(ui.Path path, + {double offsetX = 0, double offsetY = 0}) { + ui.Rect bounds = path.getBounds(); + StringBuffer sb = new StringBuffer(); + sb.write(''); + sb.write(''); + + String clipId = 'svgClipText${++_clipTextCounter}'; + sb.write(''); + + sb.write(' _initialRoute ?? '/'; + + String _initialRoute; + + bool get haveSurface => true; + + ViewportMetrics _viewportMetrics; + set viewportMetrics(ViewportMetrics metrics) { + final dimensionsChanged = + _viewportMetrics.physicalHeight != metrics.physicalHeight || + _viewportMetrics.physicalWidth != metrics.physicalWidth; + _viewportMetrics = metrics; + _runtimeController.viewportMetrics = _viewportMetrics; + if (_animator != null) { + if (dimensionsChanged) { + _animator.setDimensionChangePending(); + } + if (haveSurface) { + scheduleFrame(); + } + } + } + + void scheduleFrame({bool regenerateLayerTree = true}) { + _animator.requestFrame(regenerateLayerTree); + } + + void render(LayerTree layerTree) { + if (layerTree == null) return; + + final frameSize = ui.Size( + _viewportMetrics.physicalWidth, _viewportMetrics.physicalHeight); + + if (frameSize.isEmpty) { + return; + } + + layerTree.frameSize = frameSize; + _animator.render(layerTree); + } + + void handlePlatformMessage(PlatformMessage message) { + if (message.channel == assetChannel) { + handleAssetPlatformMessage(message); + } else { + _delegate.onEngineHandlePlatformMessage(message); + } + } + + void handleAssetPlatformMessage(PlatformMessage message) { + final response = message.response; + if (response == null) return; + + final asset = utf8.decode(message.data.buffer.asUint8List()); + if (_assetManager != null) { + _assetManager.load(asset).then((data) { + if (data != null) { + response.complete(data.buffer.asUint8List()); + } else { + response.completeEmpty(); + } + }); + } else { + response.completeEmpty(); + } + } + + FontCollection getFontCollection() => null; +} + +class Animator { + void setDimensionChangePending() {} + void render(LayerTree layerTree) {} + void requestFrame(bool regenerateLayerTree) {} +} diff --git a/lib/stub_ui/lib/src/engine/compositor/layer.dart b/lib/stub_ui/lib/src/engine/compositor/layer.dart new file mode 100644 index 0000000000000..d8c9d471c08c8 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/layer.dart @@ -0,0 +1,366 @@ +// 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. + +part of engine; + +/// A layer to be composed into a scene. +/// +/// A layer is the lowest-level rendering primitive. It represents an atomic +/// painting command. +abstract class Layer { + /// The layer that contains us as a child. + ContainerLayer parent; + + /// An estimated rectangle that this layer will draw into. + ui.Rect paintBounds = ui.Rect.zero; + + /// Whether or not this layer actually needs to be painted in the scene. + bool get needsPainting => !paintBounds.isEmpty; + + /// Pre-process this layer before painting. + /// + /// In this step, we compute the estimated [paintBounds] as well as + /// apply heuristics to prepare the render cache for pictures that + /// should be cached. + void preroll(PrerollContext prerollContext, Matrix4 matrix); + + /// Paint this layer into the scene. + void paint(PaintContext paintContext); +} + +/// A context shared by all layers during the preroll pass. +class PrerollContext { + /// A raster cache. Used to register candidates for caching. + final RasterCache rasterCache; + + PrerollContext(this.rasterCache); +} + +/// A context shared by all layers during the paint pass. +class PaintContext { + /// The canvas to paint to. + final BitmapCanvas canvas; + + /// A raster cache potentially containing pre-rendered pictures. + final RasterCache rasterCache; + + PaintContext(this.canvas, this.rasterCache); +} + +/// A layer that contains child layers. +abstract class ContainerLayer extends Layer { + final List _layers = []; + + /// Register [child] as a child of this layer. + void add(Layer child) { + child.parent = this; + _layers.add(child); + } + + @override + void preroll(PrerollContext context, Matrix4 matrix) { + paintBounds = prerollChildren(context, matrix); + } + + /// Run [preroll] on all of the child layers. + /// + /// Returns a [Rect] that covers the paint bounds of all of the child layers. + /// If all of the child layers have empty paint bounds, then the returned + /// [Rect] is empty. + ui.Rect prerollChildren(PrerollContext context, Matrix4 childMatrix) { + var childPaintBounds = ui.Rect.zero; + for (var layer in _layers) { + layer.preroll(context, childMatrix); + if (childPaintBounds.isEmpty) { + childPaintBounds = layer.paintBounds; + } else if (!layer.paintBounds.isEmpty) { + childPaintBounds = childPaintBounds.expandToInclude(layer.paintBounds); + } + } + return childPaintBounds; + } + + /// Calls [paint] on all child layers that need painting. + void paintChildren(PaintContext context) { + assert(needsPainting); + + for (var layer in _layers) { + if (layer.needsPainting) { + layer.paint(context); + } + } + } +} + +/// A layer that clips its child layers by a given [Path]. +class ClipPathLayer extends ContainerLayer { + /// The path used to clip child layers. + final ui.Path _clipPath; + + ClipPathLayer(this._clipPath); + + @override + void preroll(PrerollContext context, Matrix4 matrix) { + final childPaintBounds = prerollChildren(context, matrix); + final clipBounds = _clipPath.getBounds(); + if (childPaintBounds.overlaps(clipBounds)) { + paintBounds = childPaintBounds.intersect(clipBounds); + } + } + + @override + void paint(PaintContext context) { + assert(needsPainting); + + context.canvas.save(); + context.canvas.clipPath(_clipPath); + paintChildren(context); + context.canvas.restore(); + } +} + +/// A layer that clips its child layers by a given [Rect]. +class ClipRectLayer extends ContainerLayer { + /// The rectangle used to clip child layers. + final ui.Rect _clipRect; + + ClipRectLayer(this._clipRect); + + @override + void preroll(PrerollContext context, Matrix4 matrix) { + final childPaintBounds = prerollChildren(context, matrix); + if (childPaintBounds.overlaps(_clipRect)) { + paintBounds = childPaintBounds.intersect(_clipRect); + } + } + + @override + void paint(PaintContext context) { + assert(needsPainting); + + context.canvas.save(); + context.canvas.clipRect(_clipRect); + paintChildren(context); + context.canvas.restore(); + } +} + +/// A layer that clips its child layers by a given [RRect]. +class ClipRRectLayer extends ContainerLayer { + /// The rounded rectangle used to clip child layers. + final ui.RRect _clipRRect; + + ClipRRectLayer(this._clipRRect); + + @override + void preroll(PrerollContext context, Matrix4 matrix) { + final childPaintBounds = prerollChildren(context, matrix); + if (childPaintBounds.overlaps(_clipRRect.outerRect)) { + paintBounds = childPaintBounds.intersect(_clipRRect.outerRect); + } + } + + @override + void paint(PaintContext context) { + assert(needsPainting); + + context.canvas.save(); + context.canvas.clipRRect(_clipRRect); + paintChildren(context); + context.canvas.restore(); + } +} + +/// A layer that transforms its child layers by the given transform matrix. +class TransformLayer extends ContainerLayer { + /// The matrix with which to transform the child layers. + final Matrix4 _transform; + + TransformLayer(this._transform); + + @override + void preroll(PrerollContext context, Matrix4 matrix) { + final childMatrix = matrix * _transform; + final childPaintBounds = prerollChildren(context, childMatrix); + paintBounds = _transformRect(_transform, childPaintBounds); + } + + /// Applies the given matrix as a perspective transform to the given point. + /// + /// This function assumes the given point has a z-coordinate of 0.0. The + /// z-coordinate of the result is ignored. + static ui.Offset _transformPoint(Matrix4 transform, ui.Offset point) { + final Vector3 position3 = Vector3(point.dx, point.dy, 0.0); + final Vector3 transformed3 = transform.perspectiveTransform(position3); + return ui.Offset(transformed3.x, transformed3.y); + } + + /// Returns a rect that bounds the result of applying the given matrix as a + /// perspective transform to the given rect. + /// + /// This function assumes the given rect is in the plane with z equals 0.0. + /// The transformed rect is then projected back into the plane with z equals + /// 0.0 before computing its bounding rect. + static ui.Rect _transformRect(Matrix4 transform, ui.Rect rect) { + final ui.Offset point1 = _transformPoint(transform, rect.topLeft); + final ui.Offset point2 = _transformPoint(transform, rect.topRight); + final ui.Offset point3 = _transformPoint(transform, rect.bottomLeft); + final ui.Offset point4 = _transformPoint(transform, rect.bottomRight); + return ui.Rect.fromLTRB( + _min4(point1.dx, point2.dx, point3.dx, point4.dx), + _min4(point1.dy, point2.dy, point3.dy, point4.dy), + _max4(point1.dx, point2.dx, point3.dx, point4.dx), + _max4(point1.dy, point2.dy, point3.dy, point4.dy)); + } + + static double _min4(double a, double b, double c, double d) { + return math.min(a, math.min(b, math.min(c, d))); + } + + static double _max4(double a, double b, double c, double d) { + return math.max(a, math.max(b, math.max(c, d))); + } + + @override + void paint(PaintContext context) { + assert(needsPainting); + + context.canvas.save(); + context.canvas.transform(_transform.storage); + paintChildren(context); + context.canvas.restore(); + } +} + +/// A layer containing a [Picture]. +class PictureLayer extends Layer { + /// The picture to paint into the canvas. + final ui.Picture picture; + + /// The offset at which to paint the picture. + final ui.Offset offset; + + /// A hint to the compositor about whether this picture is complex. + final bool isComplex; + + /// A hint to the compositor that this picture is likely to change. + final bool willChange; + + PictureLayer(this.picture, this.offset, this.isComplex, this.willChange); + + @override + void preroll(PrerollContext context, Matrix4 matrix) { + final cache = context.rasterCache; + if (cache != null) { + final translateMatrix = Matrix4.identity() + ..setTranslationRaw(offset.dx, offset.dy, 0); + final cacheMatrix = translateMatrix * matrix; + cache.prepare(picture, cacheMatrix, isComplex, willChange); + } + + paintBounds = picture.cullRect.shift(offset); + } + + @override + void paint(PaintContext context) { + assert(picture != null); + assert(needsPainting); + + context.canvas.save(); + context.canvas.translate(offset.dx, offset.dy); + + if (context.rasterCache != null) { + final cacheMatrix = context.canvas.currentTransform; + final result = context.rasterCache.get(picture, cacheMatrix); + if (result.isValid) { + result.draw(context.canvas); + return; + } + } + context.canvas.drawPicture(picture); + context.canvas.restore(); + } +} + +/// A layer representing a physical shape. +/// +/// The shape clips its children to a given [Path], and casts a shadow based +/// on the given elevation. +class PhysicalShapeLayer extends ContainerLayer { + final double _elevation; + final ui.Color _color; + final ui.Color _shadowColor; + final ui.Path _path; + final ui.Clip _clipBehavior; + + PhysicalShapeLayer( + this._elevation, + this._color, + this._shadowColor, + this._path, + this._clipBehavior, + ); + + @override + void preroll(PrerollContext context, Matrix4 matrix) { + prerollChildren(context, matrix); + paintBounds = + ElevationShadow.computeShadowRect(_path.getBounds(), _elevation); + } + + @override + void paint(PaintContext context) { + assert(needsPainting); + + if (_elevation != 0) { + drawShadow(context.canvas, _path, _shadowColor, _elevation, + _color.alpha != 0xff); + } + + final paint = (ui.Paint()..color = _color).webOnlyPaintData; + if (_clipBehavior != ui.Clip.antiAliasWithSaveLayer) { + context.canvas.drawPath(_path, paint); + } + + int saveCount = context.canvas.save(); + switch (_clipBehavior) { + case ui.Clip.hardEdge: + context.canvas.clipPath(_path); + break; + case ui.Clip.antiAlias: + // TODO(het): This is supposed to be different from Clip.hardEdge in + // that it anti-aliases the clip. The canvas clipPath() method + // should support this. + context.canvas.clipPath(_path); + break; + case ui.Clip.antiAliasWithSaveLayer: + context.canvas.clipPath(_path); + context.canvas.saveLayer(paintBounds, null); + break; + case ui.Clip.none: + break; + } + + if (_clipBehavior == ui.Clip.antiAliasWithSaveLayer) { + // If we want to avoid the bleeding edge artifact + // (https://github.com/flutter/flutter/issues/18057#issue-328003931) + // using saveLayer, we have to call drawPaint instead of drawPath as + // anti-aliased drawPath will always have such artifacts. + context.canvas.drawPaint(paint); + } + + paintChildren(context); + + context.canvas.restoreToCount(saveCount); + } + + /// Draws a shadow on the given [canvas] for the given [path]. + /// + /// The blur of the shadow is decided by the [elevation], and the + /// shadow is painted with the given [color]. + static void drawShadow(BitmapCanvas canvas, ui.Path path, ui.Color color, + double elevation, bool transparentOccluder) { + canvas.drawShadow(path, color, elevation, transparentOccluder); + } +} diff --git a/lib/stub_ui/lib/src/engine/compositor/layer_scene_builder.dart b/lib/stub_ui/lib/src/engine/compositor/layer_scene_builder.dart new file mode 100644 index 0000000000000..37de1f0f9c9f2 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/layer_scene_builder.dart @@ -0,0 +1,199 @@ +// 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. + +part of engine; + +class EngineLayerImpl extends ui.EngineLayer { + final ContainerLayer _layer; + + EngineLayerImpl(this._layer); +} + +class LayerScene implements ui.Scene { + final LayerTree layerTree; + + LayerScene(Layer rootLayer) : layerTree = LayerTree() { + layerTree.rootLayer = rootLayer; + } + + @override + void dispose() {} + + @override + Future toImage(int width, int height) => null; + + @override + html.Element get webOnlyRootElement => null; +} + +class LayerSceneBuilder implements ui.SceneBuilder { + Layer rootLayer; + ContainerLayer currentLayer; + + @override + void addChildScene( + {ui.Offset offset = ui.Offset.zero, + double width = 0.0, + double height = 0.0, + ui.SceneHost sceneHost, + bool hitTestable = true}) { + throw new UnimplementedError(); + } + + @override + void addPerformanceOverlay(int enabledOptions, ui.Rect bounds) { + // We don't plan to implement this on the web. + throw UnimplementedError(); + } + + @override + void addPicture(ui.Offset offset, ui.Picture picture, + {bool isComplexHint = false, + bool willChangeHint = false, + Object webOnlyPaintedBy}) { + currentLayer + .add(PictureLayer(picture, offset, isComplexHint, willChangeHint)); + } + + @override + void addRetained(ui.EngineLayer retainedLayer) { + if (currentLayer == null) return; + currentLayer.add((retainedLayer as EngineLayerImpl)._layer); + } + + @override + void addTexture(int textureId, + {ui.Offset offset = ui.Offset.zero, + double width = 0.0, + double height = 0.0, + bool freeze = false, + Object webOnlyPaintedBy}) { + // TODO(b/128315641): implement addTexture. + } + + @override + void addPlatformView( + int viewId, { + ui.Offset offset = ui.Offset.zero, + double width = 0.0, + double height = 0.0, + }) { + // TODO(b/128317425): implement addPlatformView. + } + + @override + ui.Scene build() { + return LayerScene(rootLayer); + } + + @override + void pop() { + if (currentLayer == null) return; + currentLayer = currentLayer.parent; + } + + @override + ui.EngineLayer pushBackdropFilter(ui.ImageFilter filter, + {Object webOnlyPaintedBy}) { + throw new UnimplementedError(); + } + + @override + ui.EngineLayer pushClipPath(ui.Path path, + {ui.Clip clipBehavior = ui.Clip.antiAlias, Object webOnlyPaintedBy}) { + pushLayer(ClipPathLayer(path)); + return null; + } + + @override + ui.EngineLayer pushClipRRect(ui.RRect rrect, + {ui.Clip clipBehavior, Object webOnlyPaintedBy}) { + pushLayer(ClipRRectLayer(rrect)); + return null; + } + + @override + ui.EngineLayer pushClipRect(ui.Rect rect, + {ui.Clip clipBehavior = ui.Clip.antiAlias, Object webOnlyPaintedBy}) { + pushLayer(ClipRectLayer(rect)); + return null; + } + + @override + ui.EngineLayer pushColorFilter(ui.Color color, ui.BlendMode blendMode, + {Object webOnlyPaintedBy}) { + throw new UnimplementedError(); + } + + @override + ui.EngineLayer pushOffset(double dx, double dy, {Object webOnlyPaintedBy}) { + final matrix = Matrix4.translationValues(dx, dy, 0.0); + final layer = TransformLayer(matrix); + pushLayer(layer); + return EngineLayerImpl(layer); + } + + @override + ui.EngineLayer pushOpacity(int alpha, + {Object webOnlyPaintedBy, ui.Offset offset = ui.Offset.zero}) { + // TODO(het): Implement opacity + pushOffset(0.0, 0.0); + return null; + } + + @override + ui.EngineLayer pushPhysicalShape( + {ui.Path path, + double elevation, + ui.Color color, + ui.Color shadowColor, + ui.Clip clipBehavior = ui.Clip.none, + Object webOnlyPaintedBy}) { + final layer = + PhysicalShapeLayer(elevation, color, shadowColor, path, clipBehavior); + pushLayer(layer); + return EngineLayerImpl(layer); + } + + @override + ui.EngineLayer pushShaderMask( + ui.Shader shader, ui.Rect maskRect, ui.BlendMode blendMode, + {Object webOnlyPaintedBy}) { + throw new UnimplementedError(); + } + + @override + ui.EngineLayer pushTransform(Float64List matrix4, {Object webOnlyPaintedBy}) { + final matrix = Matrix4.fromList(matrix4); + pushLayer(TransformLayer(matrix)); + return null; + } + + @override + void setCheckerboardOffscreenLayers(bool checkerboard) { + // TODO: implement setCheckerboardOffscreenLayers + } + + @override + void setCheckerboardRasterCacheImages(bool checkerboard) { + // TODO: implement setCheckerboardRasterCacheImages + } + + @override + void setRasterizerTracingThreshold(int frameInterval) { + // TODO: implement setRasterizerTracingThreshold + } + + void pushLayer(ContainerLayer layer) { + if (rootLayer == null) { + rootLayer = currentLayer = layer; + return; + } + + if (currentLayer == null) return; + + currentLayer.add(layer); + currentLayer = layer; + } +} diff --git a/lib/stub_ui/lib/src/engine/compositor/layer_tree.dart b/lib/stub_ui/lib/src/engine/compositor/layer_tree.dart new file mode 100644 index 0000000000000..9e2dd80c9891e --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/layer_tree.dart @@ -0,0 +1,67 @@ +// 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. + +part of engine; + +/// A tree of [Layer]s that, together with a [Size] compose a frame. +class LayerTree { + /// The root of the layer tree. + Layer rootLayer; + + /// The size (in physical pixels) of the frame to paint this layer tree into. + ui.Size frameSize; + + /// Performs a preroll phase before painting the layer tree. + /// + /// In this phase, the paint boundary for each layer is computed and + /// pictures are registered with the raster cache as potential candidates + /// to raster. If [ignoreRasterCache] is `true`, then there will be no + /// attempt to register pictures to cache. + void preroll(Frame frame, {bool ignoreRasterCache = false}) { + final context = + PrerollContext(ignoreRasterCache ? null : frame.rasterCache); + rootLayer.preroll(context, Matrix4.identity()); + } + + /// Paints the layer tree into the given [frame]. + /// + /// If [ignoreRasterCache] is `true`, then the raster cache will + /// not be used. + void paint(Frame frame, {bool ignoreRasterCache = false}) { + final context = PaintContext( + frame.canvas, ignoreRasterCache ? null : frame.rasterCache); + if (rootLayer.needsPainting) { + rootLayer.paint(context); + } + } +} + +/// A single frame to be rendered. +class Frame { + /// The canvas to render this frame to. + final BitmapCanvas canvas; + + /// A cache of pre-rastered pictures. + final RasterCache rasterCache; + + Frame(this.canvas, this.rasterCache); + + /// Rasterize the given layer tree into this frame. + bool raster(LayerTree layerTree, {bool ignoreRasterCache = false}) { + layerTree.preroll(this, ignoreRasterCache: ignoreRasterCache); + layerTree.paint(this, ignoreRasterCache: ignoreRasterCache); + return true; + } +} + +/// The state of the compositor, which is persisted between frames. +class CompositorContext { + /// A cache of pictures, which is shared between successive frames. + RasterCache rasterCache; + + /// Acquire a frame using this compositor's settings. + Frame acquireFrame(BitmapCanvas canvas) { + return Frame(canvas, rasterCache); + } +} diff --git a/lib/stub_ui/lib/src/engine/compositor/platform_message.dart b/lib/stub_ui/lib/src/engine/compositor/platform_message.dart new file mode 100644 index 0000000000000..793f26622215d --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/platform_message.dart @@ -0,0 +1,18 @@ +// 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. + +part of engine; + +class PlatformMessage { + final String channel; + final ByteData data; + final PlatformMessageResponse response; + + PlatformMessage(this.channel, this.data, this.response); +} + +class PlatformMessageResponse { + void complete(Uint8List data) {} + void completeEmpty() {} +} diff --git a/lib/stub_ui/lib/src/engine/compositor/raster_cache.dart b/lib/stub_ui/lib/src/engine/compositor/raster_cache.dart new file mode 100644 index 0000000000000..fb86a93a6f0c0 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/raster_cache.dart @@ -0,0 +1,51 @@ +// 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. + +part of engine; + +/// A cache of [Picture]s that have already been rasterized. +/// +/// In the case of a [Picture] with a lot of complex drawing commands, it can +/// be faster to rasterize that [Picture] into it's own canvas and composite +/// that canvas into the scene rather than replay the drawing commands for that +/// picture into the overall scene. +/// +/// This class is responsible for deciding if a [Picture] should be cached and +/// for creating the cached [Picture]s that can be drawn directly into the +/// canvas. +class RasterCache { + /// Make a decision on whether to cache [picture] under transform [matrix]. + /// + /// This is based on heuristics such as how many times [picture] has been + /// drawn before and the complexity of the drawing commands in [picture]. + /// + /// We also take into account the current transform [matrix], because, for + /// example, a picture may be rasterized with the identity transform, but + /// when it is used, the transform is a 3x scale. In this case, compositing + /// the rendered picture would result in pixelation. So, we must use both + /// the picture and the transform as a cache key. + /// + /// The flag [isComplex] is a hint to the raster cache that this picture + /// contains complex drawing commands, and as such should be more strongly + /// considered for caching. + /// + /// The flag [willChange] is a hint to the raster cache that this picture + /// will change, and so should be less likely to be cached. + void prepare( + ui.Picture picture, Matrix4 matrix, bool isComplex, bool willChange) {} + + /// Gets a raster cache result for the [picture] at transform [matrix]. + RasterCacheResult get(ui.Picture picture, Matrix4 matrix) => + RasterCacheResult(); +} + +/// A cache entry for a given picture and matrix. +class RasterCacheResult { + /// Whether or not this result represents a rasterized picture that can be + /// drawn into the scene. + bool get isValid => false; + + /// Draws the rasterized picture into the [canvas]. + void draw(BitmapCanvas canvas) {} +} diff --git a/lib/stub_ui/lib/src/engine/compositor/rasterizer.dart b/lib/stub_ui/lib/src/engine/compositor/rasterizer.dart new file mode 100644 index 0000000000000..0b65a752dba7b --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/rasterizer.dart @@ -0,0 +1,26 @@ +// 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. + +part of engine; + +/// A class that can rasterize [LayerTree]s into a given [Surface]. +class Rasterizer { + final Surface surface; + final CompositorContext context = CompositorContext(); + + Rasterizer(this.surface); + + /// Creates a new frame from this rasterizer's surface, draws the given + /// [LayerTree] into it, and then submits the frame. + void draw(LayerTree layerTree) { + final frame = surface.acquireFrame(ui.window.physicalSize); + final canvas = frame.canvas; + final compositorFrame = context.acquireFrame(canvas); + + canvas.clear(); + + compositorFrame.raster(layerTree, ignoreRasterCache: true); + frame.submit(); + } +} diff --git a/lib/stub_ui/lib/src/engine/compositor/runtime_delegate.dart b/lib/stub_ui/lib/src/engine/compositor/runtime_delegate.dart new file mode 100644 index 0000000000000..c0c0aa0b04d6b --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/runtime_delegate.dart @@ -0,0 +1,13 @@ +// 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. + +part of engine; + +abstract class RuntimeDelegate { + String get defaultRouteName; + void scheduleFrame({bool regenerateLayerTree = true}); + void render(LayerTree layerTree); + void handlePlatformMessage(PlatformMessage message); + FontCollection getFontCollection(); +} diff --git a/lib/stub_ui/lib/src/engine/compositor/surface.dart b/lib/stub_ui/lib/src/engine/compositor/surface.dart new file mode 100644 index 0000000000000..c61eeda102798 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/surface.dart @@ -0,0 +1,51 @@ +// 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. + +part of engine; + +/// A frame which contains a canvas to be drawn into. +class SurfaceFrame { + final void Function(BitmapCanvas) submitFn; + final BitmapCanvas canvas; + SurfaceFrame(this.submitFn, this.canvas); + + /// Submit this frame to be drawn. + void submit() { + submitFn(canvas); + } +} + +/// A surface which can be drawn into by the compositor. +/// +/// The underlying representation is a [BitmapCanvas], which can be reused by +/// successive frames if they are the same size. Otherwise, a new canvas is +/// created. +class Surface { + final _CanvasCache canvasCache = _CanvasCache(); + + /// This function is called with the canvas once drawing on it has been + /// completed for a frame. + final void Function(BitmapCanvas) submitFunction; + + Surface(this.submitFunction); + + /// Acquire a frame of the given [size] containing a drawable canvas. + SurfaceFrame acquireFrame(ui.Size size) { + final canvas = canvasCache.acquireCanvas(size); + return SurfaceFrame(submitFunction, canvas); + } + + Matrix4 get rootTransformation => null; +} + +class _CanvasCache { + BitmapCanvas _canvas; + + BitmapCanvas acquireCanvas(ui.Size size) { + assert(size != null); + if (size == _canvas?.size) return _canvas; + _canvas = BitmapCanvas(ui.Offset.zero & size); + return _canvas; + } +} diff --git a/lib/stub_ui/lib/src/engine/compositor/viewport_metrics.dart b/lib/stub_ui/lib/src/engine/compositor/viewport_metrics.dart new file mode 100644 index 0000000000000..d53d021748bc6 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/compositor/viewport_metrics.dart @@ -0,0 +1,17 @@ +// 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. + +part of engine; + +class ViewportMetrics { + final double devicePixelRatio; + final double physicalWidth; + final double physicalHeight; + + const ViewportMetrics( + this.devicePixelRatio, + this.physicalWidth, + this.physicalHeight, + ); +} diff --git a/lib/stub_ui/lib/src/engine/conic.dart b/lib/stub_ui/lib/src/engine/conic.dart new file mode 100644 index 0000000000000..fd05604ae1f44 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/conic.dart @@ -0,0 +1,189 @@ +// 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. + +part of engine; + +/// Converts conic curve to a list of quadratic curves for rendering on +/// canvas or conversion to svg. +/// +/// See "High order approximation of conic sections by quadratic splines" +/// by Michael Floater, 1993. +/// Skia implementation reference: +/// https://github.com/google/skia/blob/master/src/core/SkGeometry.cpp +class Conic { + double p0x, p0y, p1x, p1y, p2x, p2y; + final double fW; + static const int _maxSubdivisionCount = 5; + + Conic(this.p0x, this.p0y, this.p1x, this.p1y, this.p2x, this.p2y, this.fW); + + /// Returns array of points for the approximation of the conic as quad(s). + /// + /// First offset is start Point. Each pair of offsets after are quadratic + /// control and end points. + List toQuads() { + final List pointList = []; + // This value specifies error bound. + const double conicTolerance = 1.0 / 4.0; + + // Based on error bound, compute how many times we should subdivide + final int subdivideCount = _computeSubdivisionCount(conicTolerance); + + // Split conic into quads, writes quad coordinates into [_pointList] and + // returns number of quads. + assert(subdivideCount > 0); + int quadCount = 1 << subdivideCount; + bool skipSubdivide = false; + pointList.add(ui.Offset(p0x, p0y)); + if (subdivideCount == _maxSubdivisionCount) { + // We have an extreme number of quads, chop this conic and check if + // it generates a pair of lines, in which case we should not subdivide. + final List dst = List(2); + _chop(dst); + final Conic conic0 = dst[0]; + final Conic conic1 = dst[1]; + // If this chop generates pair of lines no need to subdivide. + if (conic0.p1x == conic0.p2x && + conic0.p1y == conic0.p2y && + conic1.p0x == conic1.p1x && + conic1.p0y == conic1.p1y) { + final ui.Offset controlPointOffset = ui.Offset(conic0.p1x, conic0.p1y); + pointList.add(controlPointOffset); + pointList.add(controlPointOffset); + pointList.add(controlPointOffset); + pointList.add(ui.Offset(conic1.p2x, conic1.p2y)); + quadCount = 2; + skipSubdivide = true; + } + } + if (!skipSubdivide) { + _subdivide(this, subdivideCount, pointList); + } + + // If there are any non-finite generated points, pin to middle of hull. + final int pointCount = 2 * quadCount + 1; + bool hasNonFinitePoints = false; + for (int p = 0; p < pointCount; ++p) { + if (pointList[p].dx.isNaN || pointList[p].dy.isNaN) { + hasNonFinitePoints = true; + break; + } + } + if (hasNonFinitePoints) { + for (int p = 1; p < pointCount - 1; ++p) { + pointList[p] = ui.Offset(p1x, p1y); + } + } + return pointList; + } + + static bool _between(double a, double b, double c) { + return (a - b) * (c - b) <= 0; + } + + // Subdivides a conic and writes to points list. + static void _subdivide(Conic src, int level, List pointList) { + assert(level >= 0); + if (0 == level) { + // At lowest subdivision point, copy control point and end point to + // target. + pointList.add(ui.Offset(src.p1x, src.p1y)); + pointList.add(ui.Offset(src.p2x, src.p2y)); + return; + } + final List dst = List(2); + src._chop(dst); + final Conic conic0 = dst[0]; + final Conic conic1 = dst[1]; + final double startY = src.p0y; + final double endY = src.p2y; + final double cpY = src.p1y; + if (_between(startY, cpY, endY)) { + // Ensure that chopped conics maintain their y-order. + final double midY = conic0.p2y; + if (!_between(startY, midY, endY)) { + // The computed midpoint is outside end points, move it to + // closer one. + final double closerY = + (midY - startY).abs() < (midY - endY).abs() ? startY : endY; + conic0.p2y = conic1.p0y = closerY; + } + if (!_between(startY, conic0.p1y, conic0.p2y)) { + // First control point not between start and end points, move it + // to start. + conic0.p1y = startY; + } + if (!_between(conic1.p0y, conic1.p1y, endY)) { + // Second control point not between start and end points, move it + // to end. + conic1.p1y = endY; + } + // Verify that conics points are ordered. + assert(_between(startY, conic0.p1y, conic0.p2y)); + assert(_between(conic0.p1y, conic0.p2y, conic1.p1y)); + assert(_between(conic0.p2y, conic1.p1y, endY)); + } + --level; + _subdivide(conic0, level, pointList); + _subdivide(conic1, level, pointList); + } + + static double _subdivideWeightValue(double w) { + return math.sqrt(0.5 + w * 0.5); + } + + // Splits conic into 2 parts based on weight. + void _chop(List dst) { + final double scale = 1.0 / (1.0 + fW); + final double newW = _subdivideWeightValue(fW); + final ui.Offset wp1 = ui.Offset(fW * p1x, fW * p1y); + ui.Offset m = ui.Offset((p0x + (2 * wp1.dx) + p2x) * scale * 0.5, + (p0y + 2 * wp1.dy + p2y) * scale * 0.5); + if (m.dx.isNaN || m.dy.isNaN) { + final double w2 = fW * 2; + final double scaleHalf = 1.0 / (1 + fW) * 0.5; + m = ui.Offset((p0x + (w2 * p1x) + p2x) * scaleHalf, + (p0y + (w2 * p1y) + p2y) * scaleHalf); + } + dst[0] = Conic(p0x, p0y, (p0x + wp1.dx) * scale, (p0y + wp1.dy) * scale, + m.dx, m.dy, newW); + dst[1] = Conic(m.dx, m.dy, (p2x + wp1.dx) * scale, (p2y + wp1.dy) * scale, + p2x, p2y, newW); + } + + /// Computes number of binary subdivisions of the curve given + /// the tolerance. + /// + /// The number of subdivisions never exceed [_maxSubdivisionCount]. + int _computeSubdivisionCount(double tolerance) { + assert(tolerance.isFinite); + // Expecting finite coordinates. + assert(p0x.isFinite && + p1x.isFinite && + p2x.isFinite && + p0y.isFinite && + p1y.isFinite && + p2y.isFinite); + if (tolerance < 0) { + return 0; + } + // See "High order approximation of conic sections by quadratic splines" + // by Michael Floater, 1993. + // Error bound e0 = |a| |p0 - 2p1 + p2| / 4(2 + a). + final double a = fW - 1; + final double k = a / (4.0 * (2.0 + a)); + final double x = k * (p0x - 2 * p1x + p2x); + final double y = k * (p0y - 2 * p1y + p2y); + + double error = math.sqrt(x * x + y * y); + int pow2 = 0; + for (; pow2 < _maxSubdivisionCount; ++pow2) { + if (error <= tolerance) { + break; + } + error *= 0.25; + } + return pow2; + } +} diff --git a/lib/stub_ui/lib/src/engine/dom_canvas.dart b/lib/stub_ui/lib/src/engine/dom_canvas.dart new file mode 100644 index 0000000000000..276dcf881e46d --- /dev/null +++ b/lib/stub_ui/lib/src/engine/dom_canvas.dart @@ -0,0 +1,210 @@ +// 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. + +part of engine; + +/// A canvas that renders to DOM elements and CSS properties. +class DomCanvas extends EngineCanvas with SaveElementStackTracking { + final html.Element rootElement = new html.Element.tag('flt-dom-canvas'); + + DomCanvas() { + rootElement.style + ..position = 'absolute' + ..top = '0' + ..right = '0' + ..bottom = '0' + ..left = '0'; + } + + /// Prepare to reuse this canvas by clearing it's current contents. + @override + void clear() { + super.clear(); + // TODO(yjbanov): we should measure if reusing old elements is beneficial. + domRenderer.clearDom(rootElement); + } + + @override + void clipRect(ui.Rect rect) { + throw UnimplementedError(); + } + + @override + void clipRRect(ui.RRect rrect) { + throw UnimplementedError(); + } + + @override + void clipPath(ui.Path path) { + throw UnimplementedError(); + } + + @override + void drawColor(ui.Color color, ui.BlendMode blendMode) { + // TODO(yjbanov): implement blendMode + html.Element box = html.Element.tag('draw-color'); + box.style + ..position = 'absolute' + ..top = '0' + ..right = '0' + ..bottom = '0' + ..left = '0' + ..backgroundColor = color.toCssString(); + currentElement.append(box); + } + + @override + void drawLine(ui.Offset p1, ui.Offset p2, ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawPaint(ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawRect(ui.Rect rect, ui.PaintData paint) { + assert(paint.shader == null); + final rectangle = html.Element.tag('draw-rect'); + assert(() { + rectangle.setAttribute('flt-rect', '$rect'); + rectangle.setAttribute('flt-paint', '$paint'); + return true; + }()); + String effectiveTransform; + bool isStroke = paint.style == ui.PaintingStyle.stroke; + var left = math.min(rect.left, rect.right); + var right = math.max(rect.left, rect.right); + var top = math.min(rect.top, rect.bottom); + var bottom = math.max(rect.top, rect.bottom); + if (currentTransform.isIdentity()) { + if (isStroke) { + effectiveTransform = + 'translate(${left - (paint.strokeWidth / 2.0)}px, ${top - (paint.strokeWidth / 2.0)}px)'; + } else { + effectiveTransform = 'translate(${left}px, ${top}px)'; + } + } else { + // Clone to avoid mutating _transform. + Matrix4 translated = currentTransform.clone(); + if (isStroke) { + translated.translate( + left - (paint.strokeWidth / 2.0), top - (paint.strokeWidth / 2.0)); + } else { + translated.translate(left, top); + } + effectiveTransform = matrix4ToCssTransform(translated); + } + var style = rectangle.style; + style + ..position = 'absolute' + ..transformOrigin = '0 0 0' + ..transform = effectiveTransform; + + final String cssColor = paint.color?.toCssString() ?? '#000000'; + + if (paint.maskFilter != null) { + style.filter = 'blur(${paint.maskFilter.webOnlySigma}px)'; + } + + if (isStroke) { + style + ..width = '${right - left - paint.strokeWidth}px' + ..height = '${bottom - top - paint.strokeWidth}px' + ..border = '${paint.strokeWidth}px solid ${cssColor}'; + } else { + style + ..width = '${right - left}px' + ..height = '${bottom - top}px' + ..backgroundColor = cssColor; + } + + currentElement.append(rectangle); + } + + @override + void drawRRect(ui.RRect rrect, ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawDRRect(ui.RRect outer, ui.RRect inner, ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawOval(ui.Rect rect, ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawCircle(ui.Offset c, double radius, ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawPath(ui.Path path, ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawShadow(ui.Path path, ui.Color color, double elevation, + bool transparentOccluder) { + throw UnimplementedError(); + } + + @override + void drawImage(ui.Image image, ui.Offset p, ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawImageRect( + ui.Image image, ui.Rect src, ui.Rect dst, ui.PaintData paint) { + throw UnimplementedError(); + } + + @override + void drawParagraph(ui.Paragraph paragraph, ui.Offset offset) { + assert(paragraph.webOnlyIsLaidOut); + + html.Element paragraphElement = + paragraph.webOnlyGetParagraphElement().clone(true); + + String cssTransform = + matrix4ToCssTransform(transformWithOffset(currentTransform, offset)); + + final html.CssStyleDeclaration paragraphStyle = paragraphElement.style; + paragraphStyle + ..position = 'absolute' + ..transformOrigin = '0 0 0' + ..transform = cssTransform + ..whiteSpace = 'pre-wrap' + ..width = '${paragraph.width}px'; + + final ParagraphGeometricStyle style = + paragraph.webOnlyGetParagraphGeometricStyle(); + + // TODO(flutter_web): Implement the ellipsis overflow for multi-line text + // too. As a pre-requisite, we need to be able to programmatically find + // line breaks. + if (style.ellipsis != null && + (style.maxLines == null || style.maxLines == 1)) { + paragraphStyle + ..height = '${paragraph.webOnlyMaxLinesHeight}px' + ..whiteSpace = 'pre' + ..overflow = 'hidden' + ..textOverflow = 'ellipsis'; + } else if (paragraph.didExceedMaxLines) { + paragraphStyle + ..height = '${paragraph.webOnlyMaxLinesHeight}px' + ..overflowY = 'hidden'; + } else { + paragraphStyle.height = '${paragraph.height}px'; + } + + currentElement.append(paragraphElement); + } +} diff --git a/lib/stub_ui/lib/src/engine/dom_renderer.dart b/lib/stub_ui/lib/src/engine/dom_renderer.dart new file mode 100644 index 0000000000000..f6d48aa68d2b0 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/dom_renderer.dart @@ -0,0 +1,501 @@ +// 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. + +part of engine; + +class DomRenderer { + DomRenderer() { + if (assertionsEnabled) { + _debugFrameStatistics = DebugDomRendererFrameStatistics(); + } + + reset(); + + TextMeasurementService.initialize(rulerCacheCapacity: 10); + + assert(() { + _setupHotRestart(); + return true; + }()); + } + + static const int vibrateLongPress = 50; + static const int vibrateLightImpact = 10; + static const int vibrateMediumImpact = 20; + static const int vibrateHeavyImpact = 30; + static const int vibrateSelectionClick = 10; + + /// Listens to window resize events. + StreamSubscription _resizeSubscription; + + /// Contains Flutter-specific CSS rules, such as default margins and + /// paddings. + html.StyleElement _styleElement; + + /// Configures the screen, such as scaling. + html.MetaElement _viewportMeta; + + /// The element that contains the [sceneElement]. + /// + /// This element is created and inserted in the HTML DOM once. It is never + /// removed or moved. However the [sceneElement] may be replaced inside it. + /// + /// This element precedes the [glassPaneElement] so that it never receives + /// input events. All input events are processed by [glassPaneElement] and the + /// semantics tree. + html.Element get sceneHostElement => _sceneHostElement; + html.Element _sceneHostElement; + + /// The last scene element rendered by the [render] method. + html.Element get sceneElement => _sceneElement; + html.Element _sceneElement; + + /// This is state persistant across hot restarts that indicates what + /// to clear. We delay removal of old visible state to make the + /// transition appear smooth. + static const String _staleHotRestartStore = '__flutter_state'; + List _staleHotRestartState; + + void _setupHotRestart() { + // This persists across hot restarts to clear stale DOM. + _staleHotRestartState = + js_util.getProperty(html.window, _staleHotRestartStore); + if (_staleHotRestartState == null) { + _staleHotRestartState = []; + js_util.setProperty( + html.window, _staleHotRestartStore, _staleHotRestartState); + } + + registerHotRestartListener(() { + _resizeSubscription?.cancel(); + _staleHotRestartState.addAll([ + _sceneHostElement, + _glassPaneElement, + _styleElement, + _viewportMeta, + ]); + }); + } + + void _clearOnHotRestart() { + if (_staleHotRestartState.isNotEmpty) { + for (var element in _staleHotRestartState) { + element?.remove(); + } + _staleHotRestartState.clear(); + } + } + + /// We don't want to unnecessarily move DOM nodes around. If a DOM node is + /// already in the right place, skip DOM mutation. This is both faster and + /// more correct, because moving DOM nodes loses internal state, such as + /// text selection. + void renderScene(html.Element sceneElement) { + if (sceneElement != _sceneElement) { + _sceneElement?.remove(); + _sceneElement = sceneElement; + append(_sceneHostElement, sceneElement); + } + assert(() { + _clearOnHotRestart(); + return true; + }()); + } + + /// The element that captures input events, such as pointer events. + /// + /// If semantics is enabled this element also contains the semantics DOM tree, + /// which captures semantics input events. The semantics DOM tree must be a + /// child of the glass pane element so that events bubble up to the glass pane + /// if they are not handled by semantics. + html.Element get glassPaneElement => _glassPaneElement; + html.Element _glassPaneElement; + + bool get debugIsInWidgetTest => _debugIsInWidgetTest; + set debugIsInWidgetTest(bool value) { + _debugIsInWidgetTest = value; + if (_debugIsInWidgetTest) { + var logicalSize = ui.Size(800.0, 600.0); + ui.window.webOnlyDebugPhysicalSizeOverride = + logicalSize * ui.window.devicePixelRatio; + } + } + + bool _debugIsInWidgetTest = false; + + final html.Element rootElement = html.document.body; + + void addElementClass(html.Element element, String className) { + element.classes.add(className); + } + + void attachBeforeElement( + html.Element parent, html.Element before, html.Element newElement) { + assert(parent != null); + if (parent != null) { + assert(() { + if (before == null) { + return true; + } + if (before.parent != parent) { + throw Exception( + 'attachBeforeElement was called with `before` element that\'s ' + 'not a child of the `parent` element:\n' + ' before: $before\n' + ' parent: $parent', + ); + } + return true; + }()); + parent.insertBefore(newElement, before); + } + } + + html.Element createElement(String tagName, {html.Element parent}) { + html.Element element = html.document.createElement(tagName); + parent?.append(element); + return element; + } + + void append(html.Element parent, html.Element child) { + parent.append(child); + } + + void appendText(html.Element parent, String text) { + parent.appendText(text); + } + + void detachElement(html.Element element) { + element.remove(); + } + + void removeElementClass(html.Element element, String className) { + element.classes.remove(className); + } + + void setElementAttribute(html.Element element, String name, String value) { + element.setAttribute(name, value); + } + + void setElementProperty(html.Element element, String name, Object value) { + js_util.setProperty(element, name, value); + } + + void setElementStyle(html.Element element, String name, String value) { + if (value == null) { + element.style.removeProperty(name); + } else { + element.style.setProperty(name, value); + } + } + + void setText(html.Element element, String text) { + element.text = text; + } + + void removeAllChildren(html.Element element) { + element.children.clear(); + } + + html.Element getParent(html.Element element) => element.parent; + + void setTitle(String title) { + html.document.title = title; + } + + void setThemeColor(ui.Color color) { + html.MetaElement theme = html.document.querySelector('#flutterweb-theme'); + if (theme == null) { + theme = new html.MetaElement() + ..id = 'flutterweb-theme' + ..name = 'theme-color'; + html.document.head.append(theme); + } + theme.content = color.toCssString(); + } + + static const String defaultFontStyle = 'normal'; + static const String defaultFontWeight = 'normal'; + static const String defaultFontSize = '14px'; + static const String defaultFontFamily = 'sans-serif'; + static const String defaultCssFont = + '$defaultFontStyle $defaultFontWeight $defaultFontSize $defaultFontFamily'; + + void reset() { + _styleElement?.remove(); + _styleElement = new html.StyleElement(); + html.document.head.append(_styleElement); + html.CssStyleSheet sheet = _styleElement.sheet; + + // TODO(butterfly): use more efficient CSS selectors; descendant selectors + // are slow. More info: + // + // https://csswizardry.com/2011/09/writing-efficient-css-selectors/ + + // This undoes browser's default layout attributes for paragraphs. We + // compute paragraph layout ourselves. + sheet.insertRule(''' +flt-ruler-host p, flt-scene p { + margin: 0; +}''', sheet.cssRules.length); + + // This undoes browser's default painting and layout attributes of range + // input, which is used in semantics. + sheet.insertRule(''' +flt-semantics input[type=range] { + appearance: none; + -webkit-appearance: none; + width: 100%; + position: absolute; + border: none; + top: 0; + right: 0; + bottom: 0; + left: 0; +}''', sheet.cssRules.length); + + if (browserEngine == BrowserEngine.webkit) { + sheet.insertRule( + 'flt-semantics input[type=range]::-webkit-slider-thumb {' + ' -webkit-appearance: none;' + '}', + sheet.cssRules.length); + + // On iOS, the invisible semantic text field has a visible cursor and + // selection highlight. The following 2 CSS rules force everything to be + // transparent. + sheet.insertRule( + 'flt-semantics ::selection {' + ' background-color: transparent;' + '}', + sheet.cssRules.length); + } + sheet.insertRule(''' +flt-semantics input, +flt-semantics textarea, +flt-semantics [contentEditable="true"] { + caret-color: transparent; +} +''', sheet.cssRules.length); + + // By default on iOS, Safari would highlight the element that's being tapped + // on using gray background. This CSS rule disables that. + if (browserEngine == BrowserEngine.webkit) { + sheet.insertRule(''' +flt-glass-pane * { + -webkit-tap-highlight-color: transparent; +} +''', sheet.cssRules.length); + } + + final bodyElement = html.document.body; + setElementStyle(bodyElement, 'position', 'fixed'); + setElementStyle(bodyElement, 'top', '0'); + setElementStyle(bodyElement, 'right', '0'); + setElementStyle(bodyElement, 'bottom', '0'); + setElementStyle(bodyElement, 'left', '0'); + setElementStyle(bodyElement, 'overflow', 'hidden'); + setElementStyle(bodyElement, 'padding', '0'); + setElementStyle(bodyElement, 'margin', '0'); + + // TODO(yjbanov): fix this when we support KVM I/O. Currently we scroll + // using drag, and text selection interferes. + setElementStyle(bodyElement, 'user-select', 'none'); + setElementStyle(bodyElement, '-webkit-user-select', 'none'); + setElementStyle(bodyElement, '-ms-user-select', 'none'); + setElementStyle(bodyElement, '-moz-user-select', 'none'); + + // This is required to prevent the browser from doing any native touch + // handling. If we don't do this, the browser doesn't report 'pointermove' + // events properly. + setElementStyle(bodyElement, 'touch-action', 'none'); + + // These are intentionally outrageous font parameters to make sure that the + // apps fully specifies their text styles. + setElementStyle(bodyElement, 'font', defaultCssFont); + setElementStyle(bodyElement, 'color', 'red'); + + for (html.Element viewportMeta + in html.document.head.querySelectorAll('meta[name="viewport"]')) { + if (assertionsEnabled) { + // Filter out the meta tag that we ourselves placed on the page. This is + // to avoid UI flicker during hot restart. Hot restart will clean up the + // old meta tag synchronously with the first post-restart frame. + if (!viewportMeta.hasAttribute('flt-viewport')) { + print( + 'WARNING: found an existing tag. Flutter ' + 'Web uses its own viewport configuration for better compatibility ' + 'with Flutter. This tag will be replaced.', + ); + } + } + viewportMeta.remove(); + } + + // This removes a previously created meta tag. Note, however, that this does + // not remove the meta tag during hot restart. Hot restart resets all static + // variables, so this will be null upon hot restart. Instead, this tag is + // removed by _clearOnHotRestart. + _viewportMeta?.remove(); + _viewportMeta = html.MetaElement() + ..setAttribute('flt-viewport', '') + ..name = 'viewport' + ..content = 'width=device-width, initial-scale=1.0, ' + 'maximum-scale=1.0, user-scalable=no'; + html.document.head.append(_viewportMeta); + + _sceneHostElement?.remove(); + _sceneHostElement = createElement('flt-scene-host'); + bodyElement.append(_sceneHostElement); + + // IMPORTANT: the glass pane element must come after the scene element in the DOM node list so + // it can intercept input events. + _glassPaneElement?.remove(); + _glassPaneElement = createElement('flt-glass-pane'); + _glassPaneElement.style + ..position = 'absolute' + ..top = '0' + ..right = '0' + ..bottom = '0' + ..left = '0'; + bodyElement.append(_glassPaneElement); + + EngineSemanticsOwner.instance.autoEnableOnTap(this); + PointerBinding(this); + + // Hide the DOM nodes used to render the scene from accessibility, because + // the accessibility tree is built from the SemanticsNode tree as a parallel + // DOM tree. + setElementAttribute(_sceneHostElement, 'aria-hidden', 'true'); + + // We treat browser pixels as device pixels because pointer events, + // position, and sizes all use browser pixel as the unit (i.e. "px" in CSS). + // Therefore, as far as the framework is concerned the device pixel ratio + // is 1.0. + ui.window.devicePixelRatio = 1.0; + + if (browserEngine == BrowserEngine.webkit) { + // Safari sometimes gives us bogus innerWidth/innerHeight values when the + // page loads. When it changes the values to correct ones it does not + // notify of the change via `onResize`. As a workaround, we setup a + // temporary periodic timer that polls innerWidth and triggers the + // resizeListener so that the framework can react to the change. + final int initialInnerWidth = html.window.innerWidth; + // Counts how many times we checked screen size. We check up to 5 times. + int checkCount = 0; + Timer.periodic(const Duration(milliseconds: 100), (t) { + checkCount += 1; + if (initialInnerWidth != html.window.innerWidth) { + // Window size changed. Notify. + t.cancel(); + _metricsDidChange(null); + } else if (checkCount > 5) { + // Checked enough times. Stop. + t.cancel(); + } + }); + } + + _resizeSubscription = html.window.onResize.listen(_metricsDidChange); + } + + /// Called immediately after browser window metrics change. + void _metricsDidChange(html.Event event) { + if (ui.window.onMetricsChanged != null) { + ui.window.onMetricsChanged(); + } + } + + void focus(html.Element element) { + element.focus(); + } + + /// Removes all children of a DOM node. + void clearDom(html.Node node) { + while (node.lastChild != null) { + node.lastChild.remove(); + } + } + + /// The element corresponding to the only child of the root surface. + html.Element get _rootApplicationElement { + return (rootElement.children.last as html.DivElement).children.singleWhere( + (html.Element element) { + return element.tagName == 'FLT-SCENE'; + }, orElse: () => null); + } + + /// Provides haptic feedback. + Future vibrate(int durationMs) { + var navigator = html.window.navigator; + if (js_util.hasProperty(navigator, 'vibrate')) { + js_util.callMethod(navigator, 'vibrate', [durationMs]); + } + return null; + } + + String get currentHtml => _rootApplicationElement?.outerHtml ?? ''; + + DebugDomRendererFrameStatistics _debugFrameStatistics; + + DebugDomRendererFrameStatistics debugFlushFrameStatistics() { + if (!assertionsEnabled) { + throw Exception('This code should not be reachable in production.'); + } + var current = _debugFrameStatistics; + _debugFrameStatistics = DebugDomRendererFrameStatistics(); + return current; + } + + void debugRulerCacheHit() => _debugFrameStatistics.paragraphRulerCacheHits++; + void debugRulerCacheMiss() => + _debugFrameStatistics.paragraphRulerCacheMisses++; + void debugRichTextLayout() => _debugFrameStatistics.richTextLayouts++; + void debugPlainTextLayout() => _debugFrameStatistics.plainTextLayouts++; +} + +/// Miscellaneous statistics collecting during a single frame's execution. +/// +/// This is useful when profiling the app. This class should only be used when +/// assertions are enabled and therefore is not suitable for collecting any +/// time measurements. It is mostly useful for counting certain events. +class DebugDomRendererFrameStatistics { + /// The number of times we reused a previously initialized paragraph ruler to + /// measure a paragraph of text. + int paragraphRulerCacheHits = 0; + + /// The number of times we had to create a new paragraph ruler to measure a + /// paragraph of text. + int paragraphRulerCacheMisses = 0; + + /// The number of times we used a paragraph ruler to measure a paragraph of + /// text. + int get totalParagraphRulerAccesses => + paragraphRulerCacheHits + paragraphRulerCacheMisses; + + /// The number of times a paragraph of rich text was laid out this frame. + int richTextLayouts = 0; + + /// The number of times a paragraph of plain text was laid out this frame. + int plainTextLayouts = 0; + + @override + String toString() { + return ''' +Frame statistics: + Paragraph ruler cache hits: ${paragraphRulerCacheHits} + Paragraph ruler cache misses: ${paragraphRulerCacheMisses} + Paragraph ruler accesses: ${totalParagraphRulerAccesses} + Rich text layouts: ${richTextLayouts} + Plain text layouts: ${plainTextLayouts} +''' + .trim(); + } +} + +// TODO(yjbanov): Replace this with an explicit initialization function. The +// lazy initialization of statics makes it very unpredictable, as +// the constructor has side-effects. +/// Singleton DOM renderer. +final DomRenderer domRenderer = DomRenderer(); diff --git a/lib/stub_ui/lib/src/engine/engine_canvas.dart b/lib/stub_ui/lib/src/engine/engine_canvas.dart new file mode 100644 index 0000000000000..8c2c59a9a5106 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/engine_canvas.dart @@ -0,0 +1,228 @@ +// 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. + +part of engine; + +/// Defines canvas interface common across canvases that the [SceneBuilder] +/// renders to. +/// +/// This can be used either as an interface or super-class. +abstract class EngineCanvas { + /// The element that is attached to the DOM. + html.Element get rootElement; + + void dispose() { + clear(); + } + + void clear(); + + void save(); + + void restore(); + + void translate(double dx, double dy); + + void scale(double sx, double sy); + + void rotate(double radians); + + void skew(double sx, double sy); + + void transform(Float64List matrix4); + + void clipRect(ui.Rect rect); + + void clipRRect(ui.RRect rrect); + + void clipPath(ui.Path path); + + void drawColor(ui.Color color, ui.BlendMode blendMode); + + void drawLine(ui.Offset p1, ui.Offset p2, ui.PaintData paint); + + void drawPaint(ui.PaintData paint); + + void drawRect(ui.Rect rect, ui.PaintData paint); + + void drawRRect(ui.RRect rrect, ui.PaintData paint); + + void drawDRRect(ui.RRect outer, ui.RRect inner, ui.PaintData paint); + + void drawOval(ui.Rect rect, ui.PaintData paint); + + void drawCircle(ui.Offset c, double radius, ui.PaintData paint); + + void drawPath(ui.Path path, ui.PaintData paint); + + void drawShadow( + ui.Path path, ui.Color color, double elevation, bool transparentOccluder); + + void drawImage(ui.Image image, ui.Offset p, ui.PaintData paint); + + void drawImageRect( + ui.Image image, ui.Rect src, ui.Rect dst, ui.PaintData paint); + + void drawParagraph(ui.Paragraph paragraph, ui.Offset offset); +} + +/// Adds an [offset] transformation to a [transform] matrix and returns the +/// combined result. +/// +/// If the given offset is zero, returns [transform] matrix as is. Otherwise, +/// returns a new [Matrix4] object representing the combined transformation. +Matrix4 transformWithOffset(Matrix4 transform, ui.Offset offset) { + if (offset == ui.Offset.zero) { + return transform; + } + + // Clone to avoid mutating transform. + Matrix4 effectiveTransform = transform.clone(); + effectiveTransform.translate(offset.dx, offset.dy, 0.0); + return effectiveTransform; +} + +class _SaveStackEntry { + _SaveStackEntry({ + @required this.transform, + @required this.clipStack, + }); + + final Matrix4 transform; + final List<_SaveClipEntry> clipStack; +} + +/// Tagged union of clipping parameters used for canvas. +class _SaveClipEntry { + final ui.Rect rect; + final ui.RRect rrect; + final ui.Path path; + final Matrix4 currentTransform; + _SaveClipEntry.rect(this.rect, this.currentTransform) + : rrect = null, + path = null; + _SaveClipEntry.rrect(this.rrect, this.currentTransform) + : rect = null, + path = null; + _SaveClipEntry.path(this.path, this.currentTransform) + : rect = null, + rrect = null; +} + +/// Provides save stack tracking functionality to implementations of +/// [EngineCanvas]. +mixin SaveStackTracking on EngineCanvas { + static final Vector3 _unitZ = Vector3(0.0, 0.0, 1.0); + + final List<_SaveStackEntry> _saveStack = <_SaveStackEntry>[]; + + /// The stack that maintains clipping operations used when text is painted + /// onto bitmap canvas but is composited as separate element. + List<_SaveClipEntry> _clipStack; + + /// Returns whether there are active clipping regions on the canvas. + bool get isClipped => _clipStack != null; + + /// Empties the save stack and the element stack, and resets the transform + /// and clip parameters. + /// + /// Classes that override this method must call `super.clear()`. + void clear() { + _saveStack.clear(); + _clipStack = null; + _currentTransform = Matrix4.identity(); + } + + /// The current transformation matrix. + Matrix4 get currentTransform => _currentTransform; + Matrix4 _currentTransform = Matrix4.identity(); + + /// Saves current clip and transform on the save stack. + /// + /// Classes that override this method must call `super.save()`. + void save() { + _saveStack.add(_SaveStackEntry( + transform: _currentTransform.clone(), + clipStack: _clipStack == null ? null : List.from(_clipStack), + )); + } + + /// Restores current clip and transform from the save stack. + /// + /// Classes that override this method must call `super.restore()`. + void restore() { + if (_saveStack.isEmpty) { + return; + } + final _SaveStackEntry entry = _saveStack.removeLast(); + _currentTransform = entry.transform; + _clipStack = entry.clipStack; + } + + /// Multiplies the [currentTransform] matrix by a translation. + /// + /// Classes that override this method must call `super.translate()`. + void translate(double dx, double dy) { + _currentTransform.translate(dx, dy); + } + + /// Scales the [currentTransform] matrix. + /// + /// Classes that override this method must call `super.scale()`. + void scale(double sx, double sy) { + _currentTransform.scale(sx, sy); + } + + /// Rotates the [currentTransform] matrix. + /// + /// Classes that override this method must call `super.rotate()`. + void rotate(double radians) { + _currentTransform.rotate(_unitZ, radians); + } + + /// Skews the [currentTransform] matrix. + /// + /// Classes that override this method must call `super.skew()`. + void skew(double sx, double sy) { + final skewMatrix = Matrix4.identity(); + final Float64List storage = skewMatrix.storage; + storage[1] = sy; + storage[4] = sx; + _currentTransform.multiply(skewMatrix); + } + + /// Multiplies the [currentTransform] matrix by another matrix. + /// + /// Classes that override this method must call `super.transform()`. + void transform(Float64List matrix4) { + _currentTransform.multiply(Matrix4.fromFloat64List(matrix4)); + } + + /// Adds a rectangle to clipping stack. + /// + /// Classes that override this method must call `super.clipRect()`. + @override + void clipRect(ui.Rect rect) { + _clipStack ??= []; + _clipStack.add(new _SaveClipEntry.rect(rect, _currentTransform.clone())); + } + + /// Adds a round rectangle to clipping stack. + /// + /// Classes that override this method must call `super.clipRRect()`. + @override + void clipRRect(ui.RRect rrect) { + _clipStack ??= []; + _clipStack.add(new _SaveClipEntry.rrect(rrect, _currentTransform.clone())); + } + + /// Adds a path to clipping stack. + /// + /// Classes that override this method must call `super.clipPath()`. + @override + void clipPath(ui.Path path) { + _clipStack ??= []; + _clipStack.add(new _SaveClipEntry.path(path, _currentTransform.clone())); + } +} diff --git a/lib/stub_ui/lib/src/engine/history.dart b/lib/stub_ui/lib/src/engine/history.dart new file mode 100644 index 0000000000000..b54fe7fa9d56f --- /dev/null +++ b/lib/stub_ui/lib/src/engine/history.dart @@ -0,0 +1,190 @@ +// 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. + +part of engine; + +MethodCall _popRouteMethodCall = MethodCall('popRoute'); + +Map _originState = {'origin': true}; +Map _flutterState = {'flutter': true}; + +/// The origin entry is the history entry that the Flutter app landed on. It's +/// created by the browser when the user navigates to the url of the app. +bool _isOriginEntry(dynamic state) { + return state is Map && state['origin'] == true; +} + +/// The flutter entry is a history entry that we maintain on top of the origin +/// entry. It allows us to catch popstate events when the user hits the back +/// button. +bool _isFlutterEntry(dynamic state) { + return state is Map && state['flutter'] == true; +} + +/// The [BrowserHistory] class is responsible for integrating Flutter Web apps +/// with the browser history so that the back button works as expected. +/// +/// It does that by always keeping a single entry (conventionally called the +/// "flutter" entry) at the top of the browser history. That way, the browser's +/// back button always triggers a `popstate` event and never closes the app (we +/// close the app programmatically by calling [SystemNavigator.pop] when there +/// are no more app routes to be popped). +/// +/// There should only be one global instance of this class. +class BrowserHistory { + ui.LocationStrategy _locationStrategy; + ui.VoidCallback _unsubscribe; + + /// Changing the location strategy will unsubscribe from the old strategy's + /// event listeners, and subscribe to the new one. + /// + /// If the given [strategy] is the same as the existing one, nothing will + /// happen. + /// + /// If the given strategy is null, it will render this [BrowserHistory] + /// instance inactive. + set locationStrategy(ui.LocationStrategy strategy) { + if (strategy != _locationStrategy) { + _tearoffStrategy(_locationStrategy); + _locationStrategy = strategy; + _setupStrategy(_locationStrategy); + } + } + + /// The path of the current location of the user's browser. + String get currentPath => _locationStrategy?.path ?? '/'; + + /// Update the url with the given [routeName]. + void setRouteName(String routeName) { + if (_locationStrategy != null) { + _setupFlutterEntry(_locationStrategy, replace: true, path: routeName); + } + } + + /// This method does the same thing as the browser back button. + Future back() { + if (_locationStrategy != null) { + return _locationStrategy.back(); + } + return Future.value(); + } + + /// This method exits the app and goes to whatever website was active before. + Future exit() { + if (_locationStrategy != null) { + _tearoffStrategy(_locationStrategy); + // After tearing off the location strategy, we should be on the "origin" + // entry. So we need to go back one more time to exit the app. + Future backFuture = _locationStrategy.back(); + _locationStrategy = null; + return backFuture; + } + return Future.value(); + } + + String _userProvidedRouteName; + void _popStateListener(covariant html.PopStateEvent event) { + if (_isOriginEntry(event.state)) { + // If we find ourselves in the origin entry, it means that the user + // clicked the back button. + + // 1. Re-push the flutter entry to keep it always at the top of history. + _setupFlutterEntry(_locationStrategy); + + // 2. Send a 'popRoute' platform message so the app can handle it accordingly. + ui.window.onPlatformMessage( + 'flutter/navigation', + const JSONMethodCodec().encodeMethodCall(_popRouteMethodCall), + (_) {}, + ); + } else if (_isFlutterEntry(event.state)) { + // We get into this scenario when the user changes the url manually. It + // causes a new entry to be pushed on top of our "flutter" one. When this + // happens it first goes to the "else" section below where we capture the + // path into `_userProvidedRouteName` then trigger a history back which + // brings us here. + assert(_userProvidedRouteName != null); + + String newRouteName = _userProvidedRouteName; + _userProvidedRouteName = null; + + // Send a 'pushRoute' platform message so the app handles it accordingly. + ui.window.onPlatformMessage( + 'flutter/navigation', + const JSONMethodCodec().encodeMethodCall( + MethodCall('pushRoute', newRouteName), + ), + (_) {}, + ); + } else { + // The user has pushed a new entry on top of our flutter entry. This could + // happen when the user modifies the hash part of the url directly, for + // example. + + // 1. We first capture the user's desired path. + _userProvidedRouteName = currentPath; + + // 2. Then we remove the new entry. + // This will take us back to our "flutter" entry and it causes a new + // popstate event that will be handled in the "else if" section above. + _locationStrategy.back(); + } + } + + /// This method should be called when the Origin Entry is active. It just + /// replaces the state of the entry so that we can recognize it later using + /// [_isOriginEntry] inside [_popStateListener]. + void _setupOriginEntry(ui.LocationStrategy strategy) { + assert(strategy != null); + strategy.replaceState(_originState, 'origin', ''); + } + + /// This method is used manipulate the Flutter Entry which is always the + /// active entry while the Flutter app is running. + void _setupFlutterEntry( + ui.LocationStrategy strategy, { + bool replace = false, + String path, + }) { + assert(strategy != null); + path ??= currentPath; + if (replace) { + strategy.replaceState(_flutterState, 'flutter', path); + } else { + strategy.pushState(_flutterState, 'flutter', path); + } + } + + void _setupStrategy(ui.LocationStrategy strategy) { + if (strategy == null) { + return; + } + + String path = currentPath; + if (_isFlutterEntry(html.window.history.state)) { + // This could happen if the user, for example, refreshes the page. They + // will land directly on the "flutter" entry, so there's no need to setup + // the "origin" and "flutter" entries, we can safely assume they are + // already setup. + } else { + _setupOriginEntry(strategy); + _setupFlutterEntry(strategy, replace: false, path: path); + } + _unsubscribe = strategy.onPopState(_popStateListener); + } + + void _tearoffStrategy(ui.LocationStrategy strategy) { + if (strategy == null) { + return; + } + + assert(_unsubscribe != null); + _unsubscribe(); + _unsubscribe = null; + + // Remove the "flutter" entry and go back to the "origin" entry so that the + // next location strategy can start from the right spot. + strategy.back(); + } +} diff --git a/lib/stub_ui/lib/src/engine/houdini_canvas.dart b/lib/stub_ui/lib/src/engine/houdini_canvas.dart new file mode 100644 index 0000000000000..34c2c991b242b --- /dev/null +++ b/lib/stub_ui/lib/src/engine/houdini_canvas.dart @@ -0,0 +1,358 @@ +// 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. + +// TODO(yjbanov): optimization opportunities (see also houdini_painter.js) +// - collapse non-drawing paint operations +// - avoid producing DOM-based clips if there is no text +// - evaluate using stylesheets for static CSS properties +// - evaluate reusing houdini canvases +part of engine; + +/// A canvas that renders to a combination of HTML DOM and CSS Custom Paint API. +/// +/// This canvas produces paint commands for houdini_painter.js to apply. This +/// class must be kept in sync with houdini_painter.js. +class HoudiniCanvas extends EngineCanvas with SaveElementStackTracking { + final html.Element rootElement = new html.Element.tag('flt-houdini'); + + /// The rectangle positioned relative to the parent layer's coordinate system + /// where this canvas paints. + /// + /// Painting outside the bounds of this rectangle is cropped. + final ui.Rect bounds; + + HoudiniCanvas(this.bounds) { + // TODO(yjbanov): would it be faster to specify static values in a + // stylesheet and let the browser apply them? + rootElement.style + ..position = 'absolute' + ..top = '0' + ..left = '0' + ..width = '${bounds.size.width}px' + ..height = '${bounds.size.height}px' + ..backgroundImage = 'paint(flt)'; + } + + /// Prepare to reuse this canvas by clearing it's current contents. + @override + void clear() { + super.clear(); + _serializedCommands = []; + // TODO(yjbanov): we should measure if reusing old elements is beneficial. + domRenderer.clearDom(rootElement); + } + + /// Paint commands serialized for sending to the CSS custom painter. + List _serializedCommands = []; + + void apply(PaintCommand command) { + // Some commands are applied purely in HTML DOM and do not need to be + // serialized. + if (command is! PaintDrawParagraph && + command is! PaintDrawImageRect && + command is! PaintTransform) { + command.serializeToCssPaint(_serializedCommands); + } + command.apply(this); + } + + /// Sends the paint commands to the CSS custom painter for painting. + void commit() { + if (_serializedCommands.isNotEmpty) { + rootElement.style.setProperty('--flt', json.encode(_serializedCommands)); + } else { + rootElement.style.removeProperty('--flt'); + } + } + + @override + void clipRect(ui.Rect rect) { + final clip = html.Element.tag('flt-clip-rect'); + String cssTransform = matrix4ToCssTransform( + transformWithOffset(currentTransform, ui.Offset(rect.left, rect.top))); + clip.style + ..overflow = 'hidden' + ..position = 'absolute' + ..transform = cssTransform + ..width = '${rect.width}px' + ..height = '${rect.height}px'; + + // The clipping element will translate the coordinate system as well, which + // is not what a clip should do. To offset that we translate in the opposite + // direction. + super.translate(-rect.left, -rect.top); + + currentElement.append(clip); + pushElement(clip); + } + + @override + void clipRRect(ui.RRect rrect) { + final outer = rrect.outerRect; + if (rrect.isRect) { + clipRect(outer); + return; + } + + final clip = html.Element.tag('flt-clip-rrect'); + final style = clip.style; + style + ..overflow = 'hidden' + ..position = 'absolute' + ..transform = 'translate(${outer.left}px, ${outer.right}px)' + ..width = '${outer.width}px' + ..height = '${outer.height}px'; + + if (rrect.tlRadiusY == rrect.tlRadiusX) { + style.borderTopLeftRadius = '${rrect.tlRadiusX}px'; + } else { + style.borderTopLeftRadius = '${rrect.tlRadiusX}px ${rrect.tlRadiusY}px'; + } + + if (rrect.trRadiusY == rrect.trRadiusX) { + style.borderTopRightRadius = '${rrect.trRadiusX}px'; + } else { + style.borderTopRightRadius = '${rrect.trRadiusX}px ${rrect.trRadiusY}px'; + } + + if (rrect.brRadiusY == rrect.brRadiusX) { + style.borderBottomRightRadius = '${rrect.brRadiusX}px'; + } else { + style.borderBottomRightRadius = + '${rrect.brRadiusX}px ${rrect.brRadiusY}px'; + } + + if (rrect.blRadiusY == rrect.blRadiusX) { + style.borderBottomLeftRadius = '${rrect.blRadiusX}px'; + } else { + style.borderBottomLeftRadius = + '${rrect.blRadiusX}px ${rrect.blRadiusY}px'; + } + + // The clipping element will translate the coordinate system as well, which + // is not what a clip should do. To offset that we translate in the opposite + // direction. + super.translate(-rrect.left, -rrect.top); + + currentElement.append(clip); + pushElement(clip); + } + + @override + void clipPath(ui.Path path) { + // TODO(yjbanov): implement. + } + + @override + void drawColor(ui.Color color, ui.BlendMode blendMode) { + // Drawn using CSS Paint. + } + + @override + void drawLine(ui.Offset p1, ui.Offset p2, ui.PaintData paint) { + // Drawn using CSS Paint. + } + + @override + void drawPaint(ui.PaintData paint) { + // Drawn using CSS Paint. + } + + @override + void drawRect(ui.Rect rect, ui.PaintData paint) { + // Drawn using CSS Paint. + } + + @override + void drawRRect(ui.RRect rrect, ui.PaintData paint) { + // Drawn using CSS Paint. + } + + @override + void drawDRRect(ui.RRect outer, ui.RRect inner, ui.PaintData paint) { + // Drawn using CSS Paint. + } + + @override + void drawOval(ui.Rect rect, ui.PaintData paint) { + // Drawn using CSS Paint. + } + + @override + void drawCircle(ui.Offset c, double radius, ui.PaintData paint) { + // Drawn using CSS Paint. + } + + @override + void drawPath(ui.Path path, ui.PaintData paint) { + // Drawn using CSS Paint. + } + + @override + void drawShadow(ui.Path path, ui.Color color, double elevation, + bool transparentOccluder) { + // Drawn using CSS Paint. + } + + @override + void drawImage(ui.Image image, ui.Offset p, ui.PaintData paint) { + // TODO(yjbanov): implement. + } + + @override + void drawImageRect( + ui.Image image, ui.Rect src, ui.Rect dst, ui.PaintData paint) { + // TODO(yjbanov): implement src rectangle + HtmlImage htmlImage = image as HtmlImage; + html.Element imageBox = html.Element.tag('flt-img'); + String cssTransform = matrix4ToCssTransform( + transformWithOffset(currentTransform, ui.Offset(dst.left, dst.top))); + imageBox.style + ..position = 'absolute' + ..transformOrigin = '0 0 0' + ..width = '${dst.width.toInt()}px' + ..height = '${dst.height.toInt()}px' + ..transform = cssTransform + ..backgroundImage = 'url(${htmlImage.imgElement.src})' + ..backgroundRepeat = 'norepeat' + ..backgroundSize = '${dst.width}px ${dst.height}px'; + currentElement.append(imageBox); + } + + @override + void drawParagraph(ui.Paragraph paragraph, ui.Offset offset) { + assert(paragraph.webOnlyIsLaidOut); + + html.Element paragraphElement = + paragraph.webOnlyGetParagraphElement().clone(true); + + String cssTransform = + matrix4ToCssTransform(transformWithOffset(currentTransform, offset)); + + paragraphElement.style + ..position = 'absolute' + ..transformOrigin = '0 0 0' + ..transform = cssTransform + ..whiteSpace = paragraph.webOnlyDrawOnCanvas ? 'nowrap' : 'pre-wrap' + ..width = '${paragraph.width}px' + ..height = '${paragraph.height}px'; + currentElement.append(paragraphElement); + } +} + +class _SaveElementStackEntry { + _SaveElementStackEntry({ + @required this.savedElement, + @required this.transform, + }); + + final html.Element savedElement; + final Matrix4 transform; +} + +/// Provides save stack tracking functionality to implementations of +/// [EngineCanvas]. +mixin SaveElementStackTracking on EngineCanvas { + static final Vector3 _unitZ = Vector3(0.0, 0.0, 1.0); + + final List<_SaveElementStackEntry> _saveStack = <_SaveElementStackEntry>[]; + + /// The element at the top of the element stack, or [rootElement] if the stack + /// is empty. + html.Element get currentElement => + _elementStack.isEmpty ? rootElement : _elementStack.last; + + /// The stack that maintains the DOM elements used to express certain paint + /// operations, such as clips. + final List _elementStack = []; + + /// Pushes the [element] onto the element stack for the purposes of applying + /// a paint effect using a DOM element, e.g. for clipping. + /// + /// The [restore] method automatically pops the element off the stack. + void pushElement(html.Element element) { + _elementStack.add(element); + } + + /// Empties the save stack and the element stack, and resets the transform + /// and clip parameters. + /// + /// Classes that override this method must call `super.clear()`. + void clear() { + _saveStack.clear(); + _elementStack.clear(); + _currentTransform = Matrix4.identity(); + } + + /// The current transformation matrix. + Matrix4 get currentTransform => _currentTransform; + Matrix4 _currentTransform = Matrix4.identity(); + + /// Saves current clip and transform on the save stack. + /// + /// Classes that override this method must call `super.save()`. + void save() { + _saveStack.add(_SaveElementStackEntry( + savedElement: currentElement, + transform: _currentTransform.clone(), + )); + } + + /// Restores current clip and transform from the save stack. + /// + /// Classes that override this method must call `super.restore()`. + void restore() { + if (_saveStack.isEmpty) { + return; + } + final _SaveElementStackEntry entry = _saveStack.removeLast(); + _currentTransform = entry.transform; + + // Pop out of any clips. + while (currentElement != entry.savedElement) { + _elementStack.removeLast(); + } + } + + /// Multiplies the [currentTransform] matrix by a translation. + /// + /// Classes that override this method must call `super.translate()`. + void translate(double dx, double dy) { + _currentTransform.translate(dx, dy); + } + + /// Scales the [currentTransform] matrix. + /// + /// Classes that override this method must call `super.scale()`. + void scale(double sx, double sy) { + _currentTransform.scale(sx, sy); + } + + /// Rotates the [currentTransform] matrix. + /// + /// Classes that override this method must call `super.rotate()`. + void rotate(double radians) { + _currentTransform.rotate(_unitZ, radians); + } + + /// Skews the [currentTransform] matrix. + /// + /// Classes that override this method must call `super.skew()`. + void skew(double sx, double sy) { + // DO NOT USE Matrix4.skew(sx, sy)! It treats sx and sy values as radians, + // but in our case they are transform matrix values. + final Matrix4 skewMatrix = Matrix4.identity(); + final Float64List storage = skewMatrix.storage; + storage[1] = sy; + storage[4] = sx; + _currentTransform.multiply(skewMatrix); + } + + /// Multiplies the [currentTransform] matrix by another matrix. + /// + /// Classes that override this method must call `super.transform()`. + void transform(Float64List matrix4) { + _currentTransform.multiply(Matrix4.fromFloat64List(matrix4)); + } +} diff --git a/lib/stub_ui/lib/src/engine/html_image_codec.dart b/lib/stub_ui/lib/src/engine/html_image_codec.dart new file mode 100644 index 0000000000000..edcbe1d621440 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/html_image_codec.dart @@ -0,0 +1,97 @@ +// 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. + +part of engine; + +class HtmlCodec implements ui.Codec { + final String src; + + HtmlCodec(this.src); + + @override + int get frameCount => 1; + + @override + int get repetitionCount => 0; + + @override + Future getNextFrame() async { + StreamSubscription subscription; + StreamSubscription errorSubscription; + final completer = Completer(); + final html.ImageElement imgElement = html.ImageElement(); + subscription = imgElement.onLoad.listen((_) { + subscription.cancel(); + errorSubscription.cancel(); + final image = HtmlImage( + imgElement, + imgElement.naturalWidth, + imgElement.naturalHeight, + ); + completer.complete(SingleFrameInfo(image)); + }); + errorSubscription = imgElement.onError.listen((e) { + subscription.cancel(); + errorSubscription.cancel(); + completer.completeError(e); + }); + imgElement.src = src; + return completer.future; + } + + @override + void dispose() {} +} + +class HtmlBlobCodec extends HtmlCodec { + final html.Blob blob; + + HtmlBlobCodec(this.blob) : super(html.Url.createObjectUrlFromBlob(blob)); + + @override + void dispose() { + html.Url.revokeObjectUrl(src); + } +} + +class SingleFrameInfo implements ui.FrameInfo { + SingleFrameInfo(this.image); + + @override + Duration get duration => const Duration(milliseconds: 0); + + @override + final ui.Image image; +} + +class HtmlImage implements ui.Image { + final html.ImageElement imgElement; + + HtmlImage(this.imgElement, this.width, this.height); + + @override + void dispose() { + // Do nothing. The codec that owns this image should take care of + // releasing the object url. + } + + @override + final int width; + + @override + final int height; + + @override + Future toByteData( + {ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba}) { + return futurize((Callback callback) { + return _toByteData(format.index, (Uint8List encoded) { + callback(encoded?.buffer?.asByteData()); + }); + }); + } + + /// Returns an error message on failure, null on success. + String _toByteData(int format, Callback callback) => null; +} diff --git a/lib/stub_ui/lib/src/engine/keyboard.dart b/lib/stub_ui/lib/src/engine/keyboard.dart new file mode 100644 index 0000000000000..af21808eef5d0 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/keyboard.dart @@ -0,0 +1,79 @@ +// 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. + +part of engine; + +/// Provides keyboard bindings, such as the `flutter/keyevent` channel. +class Keyboard { + /// Initializes the [Keyboard] singleton. + /// + /// Use the [instance] getter to get the singleton after calling this method. + static void initialize() { + _instance ??= Keyboard._(); + } + + /// The [Keyboard] singleton. + static Keyboard get instance => _instance; + static Keyboard _instance; + + html.EventListener _keydownListener; + html.EventListener _keyupListener; + + Keyboard._() { + _keydownListener = (html.Event event) { + _handleHtmlEvent(event); + }; + html.window.addEventListener('keydown', _keydownListener); + + _keyupListener = (html.Event event) { + _handleHtmlEvent(event); + }; + html.window.addEventListener('keyup', _keyupListener); + registerHotRestartListener(() { + dispose(); + }); + } + + /// Uninitializes the [Keyboard] singleton. + /// + /// After calling this method this object becomes unusable and [instance] + /// becomes `null`. Call [initialize] again to initialize a new singleton. + void dispose() { + html.window.removeEventListener('keydown', _keydownListener); + html.window.removeEventListener('keyup', _keyupListener); + _keydownListener = null; + _keyupListener = null; + _instance = null; + } + + final JSONMessageCodec _messageCodec = JSONMessageCodec(); + + void _handleHtmlEvent(html.KeyboardEvent event) { + final Map eventData = { + 'type': event.type, + // TODO(yjbanov): this emulates Android because that the only reasonable + // thing to map to right now (the other choice is fuchsia). + // However, eventually we need to have something that maps + // better to Web. + 'keymap': 'android', + 'keyCode': event.keyCode, + }; + + // TODO(yjbanov): The browser does not report `charCode` for 'keydown' and + // 'keyup', only for 'keypress'. This restores the value + // from the 'key' field. However, we need to verify how + // many code units a single key can have. Right now it + // assumes exactly one unit (that's what Flutter framework + // expects). But we'll need a different strategy if other + // code unit counts are possible. + if (event.key.codeUnits.length == 1) { + eventData['codePoint'] = event.key.codeUnits.first; + } + + ui.window.onPlatformMessage('flutter/keyevent', + _messageCodec.encodeMessage(eventData), _noopCallback); + } +} + +void _noopCallback(ByteData data) {} diff --git a/lib/stub_ui/lib/src/engine/onscreen_logging.dart b/lib/stub_ui/lib/src/engine/onscreen_logging.dart new file mode 100644 index 0000000000000..336bd0ff7e854 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/onscreen_logging.dart @@ -0,0 +1,77 @@ +// 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. + +part of engine; + +html.Element _logElement; +html.Element _logContainer; +List<_LogMessage> _logBuffer = <_LogMessage>[]; + +class _LogMessage { + _LogMessage(this.message); + + int duplicateCount = 1; + final String message; + + @override + String toString() { + if (duplicateCount == 1) { + return message; + } + return '${duplicateCount}x $message'; + } +} + +/// A drop-in replacement for [print] that prints on the screen into a +/// fixed-positioned element. +/// +/// This is useful, for example, for print-debugging on iOS when debugging over +/// USB is not available. +void printOnScreen(Object object) { + if (_logElement == null) { + _initialize(); + } + + final String message = '$object'; + if (_logBuffer.isNotEmpty && _logBuffer.last.message == message) { + _logBuffer.last.duplicateCount += 1; + } else { + _logBuffer.add(_LogMessage(message)); + } + + if (_logBuffer.length > 80) { + _logBuffer = _logBuffer.sublist(_logBuffer.length - 50); + } + + _logContainer.text = _logBuffer.join('\n'); + + // Also log to console for browsers that give you access to it. + print(message); +} + +void _initialize() { + _logElement = html.Element.tag('flt-onscreen-log'); + _logElement.setAttribute('aria-hidden', 'true'); + _logElement.style + ..position = 'fixed' + ..left = '0' + ..right = '0' + ..bottom = '0' + ..height = '25%' + ..backgroundColor = 'rgba(0, 0, 0, 0.85)' + ..color = 'white' + ..fontSize = '8px' + ..whiteSpace = 'pre-wrap' + ..overflow = 'hidden' + ..zIndex = '1000'; + + _logContainer = html.Element.tag('flt-log-container'); + _logContainer.setAttribute('aria-hidden', 'true'); + _logContainer.style + ..position = 'absolute' + ..bottom = '0'; + _logElement.append(_logContainer); + + html.document.body.append(_logElement); +} diff --git a/lib/stub_ui/lib/src/engine/path_to_svg.dart b/lib/stub_ui/lib/src/engine/path_to_svg.dart new file mode 100644 index 0000000000000..75587a165322e --- /dev/null +++ b/lib/stub_ui/lib/src/engine/path_to_svg.dart @@ -0,0 +1,190 @@ +// 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. + +part of engine; + +/// Converts [path] to SVG path syntax to be used as "d" attribute in path +/// element. +void pathToSvg(ui.Path path, StringBuffer sb, + {double offsetX = 0, double offsetY = 0}) { + for (Subpath subPath in path.subpaths) { + for (PathCommand command in subPath.commands) { + switch (command.type) { + case PathCommandTypes.moveTo: + MoveTo moveTo = command; + sb.write('M ${moveTo.x + offsetX} ${moveTo.y + offsetY}'); + break; + case PathCommandTypes.lineTo: + LineTo lineTo = command; + sb.write('L ${lineTo.x + offsetX} ${lineTo.y + offsetY}'); + break; + case PathCommandTypes.bezierCurveTo: + BezierCurveTo curve = command; + sb.write('C ${curve.x1 + offsetX} ${curve.y1 + offsetY} ' + '${curve.x2 + offsetX} ${curve.y2 + offsetY} ${curve.x3 + offsetX} ${curve.y3 + offsetY}'); + break; + case PathCommandTypes.quadraticCurveTo: + QuadraticCurveTo quadraticCurveTo = command; + sb.write( + 'Q ${quadraticCurveTo.x1 + offsetX} ${quadraticCurveTo.y1 + offsetY} ' + '${quadraticCurveTo.x2 + offsetX} ${quadraticCurveTo.y2 + offsetY}'); + break; + case PathCommandTypes.close: + sb.write('Z'); + break; + case PathCommandTypes.ellipse: + Ellipse ellipse = command; + // Handle edge case where start and end points are the same by drawing + // 2 half arcs. + if ((ellipse.endAngle - ellipse.startAngle) % (2 * math.pi) == 0.0) { + _writeEllipse( + sb, + ellipse.x + offsetX, + ellipse.y + offsetY, + ellipse.radiusX, + ellipse.radiusY, + ellipse.rotation, + -math.pi, + 0, + ellipse.anticlockwise, + moveToStartPoint: true); + _writeEllipse( + sb, + ellipse.x + offsetX, + ellipse.y + offsetY, + ellipse.radiusX, + ellipse.radiusY, + ellipse.rotation, + 0, + math.pi, + ellipse.anticlockwise); + } else { + _writeEllipse( + sb, + ellipse.x + offsetX, + ellipse.y + offsetY, + ellipse.radiusX, + ellipse.radiusY, + ellipse.rotation, + ellipse.startAngle, + ellipse.endAngle, + ellipse.anticlockwise); + } + break; + case PathCommandTypes.rRect: + RRectCommand rrectCommand = command; + ui.RRect rrect = rrectCommand.rrect; + var left = rrect.left + offsetX; + var right = rrect.right + offsetX; + var top = rrect.top + offsetY; + var bottom = rrect.bottom + offsetY; + if (left > right) { + left = right; + right = rrect.left + offsetX; + } + if (top > bottom) { + top = bottom; + bottom = rrect.top + offsetY; + } + var trRadiusX = rrect.trRadiusX.abs(); + var tlRadiusX = rrect.tlRadiusX.abs(); + var trRadiusY = rrect.trRadiusY.abs(); + var tlRadiusY = rrect.tlRadiusY.abs(); + var blRadiusX = rrect.blRadiusX.abs(); + var brRadiusX = rrect.brRadiusX.abs(); + var blRadiusY = rrect.blRadiusY.abs(); + var brRadiusY = rrect.brRadiusY.abs(); + + sb.write('L ${left + trRadiusX} $top '); + // Top side and top-right corner + sb.write('M ${right - trRadiusX} $top '); + _writeEllipse(sb, right - trRadiusX, top + trRadiusY, trRadiusX, + trRadiusY, 0, 1.5 * math.pi, 2.0 * math.pi, false); + // Right side and bottom-right corner + sb.write('L $right ${bottom - brRadiusY} '); + _writeEllipse(sb, right - brRadiusX, bottom - brRadiusY, brRadiusX, + brRadiusY, 0, 0, 0.5 * math.pi, false); + // Bottom side and bottom-left corner + sb.write('L ${left + blRadiusX} $bottom '); + _writeEllipse(sb, left + blRadiusX, bottom - blRadiusY, blRadiusX, + blRadiusY, 0, 0.5 * math.pi, math.pi, false); + // Left side and top-left corner + sb.write('L $left ${top + tlRadiusY} '); + _writeEllipse( + sb, + left + tlRadiusX, + top + tlRadiusY, + tlRadiusX, + tlRadiusY, + 0, + math.pi, + 1.5 * math.pi, + false, + ); + break; + case PathCommandTypes.rect: + RectCommand rectCommand = command; + bool horizontalSwap = rectCommand.width < 0; + final left = offsetX + + (horizontalSwap + ? rectCommand.x - rectCommand.width + : rectCommand.x); + final width = horizontalSwap ? -rectCommand.width : rectCommand.width; + bool verticalSwap = rectCommand.height < 0; + final top = offsetY + + (verticalSwap + ? rectCommand.y - rectCommand.height + : rectCommand.y); + final height = + verticalSwap ? -rectCommand.height : rectCommand.height; + sb.write('M $left $top '); + sb.write('L ${left + width} $top '); + sb.write('L ${left + width} ${top + height} '); + sb.write('L $left ${top + height} '); + sb.write('L $left $top '); + break; + default: + throw new UnimplementedError('Unknown path command $command'); + } + } + } +} + +// See https://www.w3.org/TR/SVG/implnote.html B.2.3. Conversion from center to +// endpoint parameterization. +void _writeEllipse( + StringBuffer sb, + double cx, + double cy, + double radiusX, + double radiusY, + double rotation, + double startAngle, + double endAngle, + bool antiClockwise, + {bool moveToStartPoint = false}) { + double cosRotation = math.cos(rotation); + double sinRotation = math.sin(rotation); + double x = math.cos(startAngle) * radiusX; + double y = math.sin(startAngle) * radiusY; + + double startPx = cx + (cosRotation * x - sinRotation * y); + double startPy = cy + (sinRotation * x + cosRotation * y); + + double xe = math.cos(endAngle) * radiusX; + double ye = math.sin(endAngle) * radiusY; + + double endPx = cx + (cosRotation * xe - sinRotation * ye); + double endPy = cy + (sinRotation * xe + cosRotation * ye); + + double delta = endAngle - startAngle; + bool largeArc = delta.abs() > math.pi; + + double rotationDeg = rotation / math.pi * 180.0; + if (moveToStartPoint) { + sb.write('M $startPx $startPy '); + } + sb.write('A $radiusX $radiusY ${rotationDeg} ' + '${largeArc ? 1 : 0} ${antiClockwise ? 0 : 1} $endPx $endPy'); +} diff --git a/lib/stub_ui/lib/src/engine/pointer_binding.dart b/lib/stub_ui/lib/src/engine/pointer_binding.dart new file mode 100644 index 0000000000000..9e10efcdd6c53 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/pointer_binding.dart @@ -0,0 +1,462 @@ +// 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. + +part of engine; + +/// Set this flag to true to see all the fired events in the console. +const _debugLogPointerEvents = false; + +/// The signature of a callback that handles pointer events. +typedef PointerDataCallback = void Function(List); + +class PointerBinding { + /// The singleton instance of this object. + static PointerBinding get instance => _instance; + static PointerBinding _instance; + + PointerBinding(this.domRenderer) { + if (_instance == null) { + _instance = this; + _detector = const PointerSupportDetector(); + _adapter = _createAdapter(); + } + assert(() { + registerHotRestartListener(() { + _adapter?.clearListeners(); + }); + return true; + }()); + } + + final DomRenderer domRenderer; + PointerSupportDetector _detector; + BaseAdapter _adapter; + + /// Should be used in tests to define custom detection of pointer support. + /// + /// ```dart + /// // Forces PointerBinding to use mouse events. + /// class MyTestDetector extends PointerSupportDetector { + /// @override + /// final bool hasPointerEvents = false; + /// + /// @override + /// final bool hasTouchEvents = false; + /// + /// @override + /// final bool hasMouseEvents = true; + /// } + /// + /// PointerBinding.instance.debugOverrideDetector(MyTestDetector()); + /// ``` + void debugOverrideDetector(PointerSupportDetector newDetector) { + if (newDetector == null) { + newDetector = const PointerSupportDetector(); + } + // When changing the detector, we need to swap the adapter. + if (newDetector != _detector) { + _detector = newDetector; + _adapter?.clearListeners(); + _adapter = _createAdapter(); + } + } + + BaseAdapter _createAdapter() { + if (_detector.hasPointerEvents) { + return PointerAdapter(_onPointerData, domRenderer); + } + if (_detector.hasTouchEvents) { + return TouchAdapter(_onPointerData, domRenderer); + } + if (_detector.hasMouseEvents) { + return MouseAdapter(_onPointerData, domRenderer); + } + return null; + } + + void _onPointerData(List data) { + ui.PointerDataPacket packet = ui.PointerDataPacket(data: data); + ui.window.onPointerDataPacket(packet); + } +} + +class PointerSupportDetector { + const PointerSupportDetector(); + + bool get hasPointerEvents => js_util.hasProperty(html.window, 'PointerEvent'); + bool get hasTouchEvents => js_util.hasProperty(html.window, 'TouchEvent'); + bool get hasMouseEvents => js_util.hasProperty(html.window, 'MouseEvent'); + + String toString() => + 'pointers:$hasPointerEvents, touch:$hasTouchEvents, mouse:$hasMouseEvents'; +} + +/// Common functionality that's shared among adapters. +abstract class BaseAdapter { + static final Map _listeners = + {}; + + final DomRenderer domRenderer; + PointerDataCallback _callback; + Map _isDownMap = {}; + bool _isButtonDown(int button) { + return _isDownMap[button] == true; + } + + void _updateButtonDownState(int button, bool value) { + _isDownMap[button] = value; + } + + BaseAdapter(this._callback, this.domRenderer) { + _setup(); + } + + /// Each subclass is expected to override this method to attach its own event + /// listeners and convert events into pointer events. + void _setup(); + + /// Remove all active event listeners. + void clearListeners() { + final html.Element glassPane = domRenderer.glassPaneElement; + _listeners.forEach((String eventName, html.EventListener listener) { + glassPane.removeEventListener(eventName, listener); + }); + _listeners.clear(); + } + + void _addEventListener(String eventName, html.EventListener handler) { + html.EventListener loggedHandler = (html.Event event) { + if (_debugLogPointerEvents) print(event.type); + // Report the event to semantics. This information is used to debounce + // browser gestures. Semantics tells us whether it is safe to forward + // the event to the framework. + if (EngineSemanticsOwner.instance.receiveGlobalEvent(event)) { + handler(event); + } + }; + _listeners[eventName] = loggedHandler; + domRenderer.glassPaneElement + .addEventListener(eventName, loggedHandler, true); + } +} + +const int _kPrimaryMouseButton = 0x1; +const int _kSecondaryMouseButton = 0x2; + +int _pointerButtonFromHtmlEvent(html.Event event) { + if (event is html.PointerEvent) { + final html.PointerEvent pointerEvent = event; + return pointerEvent.button == 2 + ? _kSecondaryMouseButton + : _kPrimaryMouseButton; + } else if (event is html.MouseEvent) { + final html.MouseEvent mouseEvent = event; + return mouseEvent.button == 2 + ? _kSecondaryMouseButton + : _kPrimaryMouseButton; + } + return _kPrimaryMouseButton; +} + +/// Adapter class to be used with browsers that support native pointer events. +class PointerAdapter extends BaseAdapter { + PointerAdapter(PointerDataCallback callback, DomRenderer domRenderer) + : super(callback, domRenderer); + + void _setup() { + _addEventListener('pointerdown', (html.Event event) { + int pointerButton = _pointerButtonFromHtmlEvent(event); + if (_isButtonDown(pointerButton)) { + // TODO(flutter_web): Remove this temporary fix for right click + // on web platform once context guesture is implemented. + _callback(_convertEventToPointerData(ui.PointerChange.up, event)); + } + _updateButtonDownState(pointerButton, true); + _callback(_convertEventToPointerData(ui.PointerChange.down, event)); + }); + + _addEventListener('pointermove', (html.Event event) { + // TODO(flutter_web): During a drag operation pointermove will set + // button to -1 as opposed to mouse move which sets it to 2. + // This check is currently defaulting to primary button for now. + // Change this when context gesture is implemented in flutter framework. + if (!_isButtonDown(_pointerButtonFromHtmlEvent(event))) return; + _callback(_convertEventToPointerData(ui.PointerChange.move, event)); + }); + + _addEventListener('pointerup', (html.Event event) { + // The pointer could have been released by a `pointerout` event, in which + // case `pointerup` should have no effect. + int pointerButton = _pointerButtonFromHtmlEvent(event); + if (!_isButtonDown(pointerButton)) return; + _updateButtonDownState(pointerButton, false); + _callback(_convertEventToPointerData(ui.PointerChange.up, event)); + }); + + // A browser fires cancel event if it concludes the pointer will no longer + // be able to generate events (example: device is deactivated) + _addEventListener('pointercancel', (html.Event event) { + _callback(_convertEventToPointerData(ui.PointerChange.cancel, event)); + }); + + _addWheelEventListener((html.WheelEvent event) { + if (_debugLogPointerEvents) print(event.type); + _callback(_convertWheelEventToPointerData(event)); + // Prevent default so mouse wheel event doesn't get converted to + // a scroll event that semantic nodes would process. + event.preventDefault(); + }); + } + + List _convertEventToPointerData( + ui.PointerChange change, + html.PointerEvent evt, + ) { + List allEvents = _expandEvents(evt); + List data = List(allEvents.length); + for (int i = 0; i < allEvents.length; i++) { + html.PointerEvent event = allEvents[i]; + data[i] = ui.PointerData( + change: change, + timeStamp: _eventTimeStampToDuration(event.timeStamp), + kind: _pointerTypeToDeviceKind(event.pointerType), + device: _uniqueDeviceIdFromType(event.pointerType), + physicalX: event.client.x, + physicalY: event.client.y, + buttons: event.buttons, + pressure: event.pressure, + pressureMin: 0.0, + pressureMax: 1.0, + tilt: _computeHighestTilt(event), + ); + } + return data; + } + + List _expandEvents(html.PointerEvent event) { + // For browsers that don't support `getCoalescedEvents`, we fallback to + // using the original event. + if (js_util.hasProperty(event, 'getCoalescedEvents')) { + var coalescedEvents = event.getCoalescedEvents(); + // Some events don't perform coalescing, so they return an empty list. In + // that case, we also fallback to using the original event. + if (coalescedEvents.isNotEmpty) { + return coalescedEvents; + } + } + return [event]; + } + + ui.PointerDeviceKind _pointerTypeToDeviceKind(String pointerType) { + switch (pointerType) { + case 'mouse': + return ui.PointerDeviceKind.mouse; + case 'pen': + return ui.PointerDeviceKind.stylus; + case 'touch': + return ui.PointerDeviceKind.touch; + default: + return ui.PointerDeviceKind.unknown; + } + } + + /// Tilt angle is -90 to + 90. Take maximum deflection and convert to radians. + double _computeHighestTilt(html.PointerEvent e) => + (e.tiltX.abs() > e.tiltY.abs() ? e.tiltX : e.tiltY).toDouble() / + 180.0 * + math.pi; +} + +/// Adapter to be used with browsers that support touch events. +class TouchAdapter extends BaseAdapter { + TouchAdapter(PointerDataCallback callback, DomRenderer domRenderer) + : super(callback, domRenderer); + + void _setup() { + _addEventListener('touchstart', (html.Event event) { + _updateButtonDownState(_kPrimaryMouseButton, true); + _callback(_convertEventToPointerData(ui.PointerChange.down, event)); + }); + + _addEventListener('touchmove', (html.Event event) { + event.preventDefault(); // Prevents standard overscroll on iOS/Webkit. + if (!_isButtonDown(_kPrimaryMouseButton)) return; + _callback(_convertEventToPointerData(ui.PointerChange.move, event)); + }); + + _addEventListener('touchend', (html.Event event) { + _updateButtonDownState(_kPrimaryMouseButton, false); + _callback(_convertEventToPointerData(ui.PointerChange.up, event)); + }); + + _addEventListener('touchcancel', (html.Event event) { + _callback(_convertEventToPointerData(ui.PointerChange.cancel, event)); + }); + } + + List _convertEventToPointerData( + ui.PointerChange change, + html.TouchEvent event, + ) { + var touch = event.changedTouches.first; + return [ + ui.PointerData( + change: change, + timeStamp: _eventTimeStampToDuration(event.timeStamp), + kind: ui.PointerDeviceKind.touch, + signalKind: ui.PointerSignalKind.none, + device: _uniqueDeviceIdFromType('touch'), + physicalX: touch.client.x, + physicalY: touch.client.y, + pressure: 1.0, + pressureMin: 0.0, + pressureMax: 1.0, + ) + ]; + } +} + +/// Adapter to be used with browsers that support mouse events. +class MouseAdapter extends BaseAdapter { + MouseAdapter(PointerDataCallback callback, DomRenderer domRenderer) + : super(callback, domRenderer); + + void _setup() { + _addEventListener('mousedown', (html.Event event) { + int pointerButton = _pointerButtonFromHtmlEvent(event); + if (_isButtonDown(pointerButton)) { + // TODO(flutter_web): Remove this temporary fix for right click + // on web platform once context guesture is implemented. + _callback(_convertEventToPointerData(ui.PointerChange.up, event)); + } + _updateButtonDownState(pointerButton, true); + _callback(_convertEventToPointerData(ui.PointerChange.down, event)); + }); + + _addEventListener('mousemove', (html.Event event) { + if (!_isButtonDown(_pointerButtonFromHtmlEvent(event))) return; + _callback(_convertEventToPointerData(ui.PointerChange.move, event)); + }); + + _addEventListener('mouseup', (html.Event event) { + _updateButtonDownState(_pointerButtonFromHtmlEvent(event), false); + _callback(_convertEventToPointerData(ui.PointerChange.up, event)); + }); + + _addWheelEventListener((html.WheelEvent event) { + if (_debugLogPointerEvents) print(event.type); + _callback(_convertWheelEventToPointerData(event)); + event.preventDefault(); + }); + } + + List _convertEventToPointerData( + ui.PointerChange change, + html.MouseEvent event, + ) { + return [ + ui.PointerData( + change: change, + timeStamp: _eventTimeStampToDuration(event.timeStamp), + kind: ui.PointerDeviceKind.mouse, + signalKind: ui.PointerSignalKind.none, + device: _uniqueDeviceIdFromType('mouse'), + physicalX: event.client.x, + physicalY: event.client.y, + buttons: event.buttons, + pressure: 1.0, + pressureMin: 0.0, + pressureMax: 1.0, + ) + ]; + } +} + +/// Convert a floating number timestamp (in milliseconds) to a [Duration] by +/// splitting it into two integer components: milliseconds + microseconds. +Duration _eventTimeStampToDuration(num milliseconds) { + int ms = milliseconds.toInt(); + int micro = + ((milliseconds - ms) * Duration.microsecondsPerMillisecond).toInt(); + return new Duration(milliseconds: ms, microseconds: micro); +} + +List _convertWheelEventToPointerData( + html.WheelEvent event, +) { + const int domDeltaPixel = 0x00; + const int domDeltaLine = 0x01; + const int domDeltaPage = 0x02; + + // Flutter only supports pixel scroll delta. Convert deltaMode values + // to pixels. + double deltaX = event.deltaX; + double deltaY = event.deltaY; + switch (event.deltaMode) { + case domDeltaLine: + deltaX *= 32.0; + deltaY *= 32.0; + break; + case domDeltaPage: + deltaX *= ui.window.physicalSize.width; + deltaY *= ui.window.physicalSize.height; + break; + case domDeltaPixel: + default: + break; + } + return [ + ui.PointerData( + change: ui.PointerChange.add, + timeStamp: _eventTimeStampToDuration(event.timeStamp), + kind: ui.PointerDeviceKind.mouse, + signalKind: ui.PointerSignalKind.scroll, + device: _uniqueDeviceIdFromType('mouse'), + physicalX: event.client.x, + physicalY: event.client.y, + buttons: event.buttons, + pressure: 1.0, + pressureMin: 0.0, + pressureMax: 1.0, + scrollDeltaX: deltaX, + scrollDeltaY: deltaY, + ), + ui.PointerData( + change: ui.PointerChange.hover, + timeStamp: _eventTimeStampToDuration(event.timeStamp), + kind: ui.PointerDeviceKind.mouse, + signalKind: ui.PointerSignalKind.scroll, + device: _uniqueDeviceIdFromType('mouse'), + physicalX: event.client.x, + physicalY: event.client.y, + buttons: event.buttons, + pressure: 1.0, + pressureMin: 0.0, + pressureMax: 1.0, + scrollDeltaX: deltaX, + scrollDeltaY: deltaY, + ) + ]; +} + +void _addWheelEventListener(void listener(html.WheelEvent e)) { + var eventOptions = js_util.newObject(); + js_util.setProperty(eventOptions, 'passive', false); + js_util.callMethod( + PointerBinding.instance.domRenderer.glassPaneElement, + 'addEventListener', + ['wheel', js.allowInterop((event) => listener(event)), eventOptions]); +} + +// Unique device id for each pointer type. +// TODO(flutter_web): Stabilize/Prepopulate device ids. +final Map _devices = {}; +int _uniqueDeviceIdFromType(String type) { + var id = _devices[type]; + if (id == null) { + id = _devices.length; + _devices[type] = id; + } + return id; +} diff --git a/lib/stub_ui/lib/src/engine/recording_canvas.dart b/lib/stub_ui/lib/src/engine/recording_canvas.dart new file mode 100644 index 0000000000000..428c91b3048f8 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/recording_canvas.dart @@ -0,0 +1,1512 @@ +// 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. + +part of engine; + +/// Enable this to print every command applied by a canvas. +const bool _debugDumpPaintCommands = false; + +/// Records canvas commands to be applied to a [EngineCanvas]. +/// +/// See [Canvas] for docs for these methods. +class RecordingCanvas { + /// Maximum paintable bounds for this canvas. + final _PaintBounds _paintBounds; + final _commands = []; + + RecordingCanvas(ui.Rect bounds) : this._paintBounds = _PaintBounds(bounds); + + /// Whether this canvas is doing arbitrary paint operations not expressible + /// via DOM elements. + bool get hasArbitraryPaint => _hasArbitraryPaint; + bool _hasArbitraryPaint = false; + + /// Forces arbitrary paint even for simple pictures. + /// + /// This is useful for testing bitmap canvas when otherwise the compositor + /// would prefer a DOM canvas. + void debugEnforceArbitraryPaint() { + _hasArbitraryPaint = true; + } + + /// Whether this canvas contain drawing operations. + /// + /// Some pictures are created but only contain operations that do not result + /// in any pixels on the screen. For example, they will only contain saves, + /// restores, and translates. This happens when a parent [RenderObject] + /// prepares the canvas for its children to paint to, but the child ends up + /// not painting anything, such as when an empty [SizedBox] is used to add a + /// margin between two widgets. + bool get didDraw => _didDraw; + bool _didDraw = false; + + /// Computes paint bounds based on estimated [bounds] and transforms. + ui.Rect computePaintBounds() { + return _paintBounds.computeBounds(); + } + + /// Applies the recorded commands onto an [engineCanvas]. + void apply(EngineCanvas engineCanvas) { + if (_debugDumpPaintCommands) { + final StringBuffer debugBuf = StringBuffer(); + debugBuf.writeln( + '--- Applying RecordingCanvas to ${engineCanvas.runtimeType} ' + 'with bounds $_paintBounds'); + for (var i = 0; i < _commands.length; i++) { + var command = _commands[i]; + debugBuf.writeln('ctx.$command;'); + command.apply(engineCanvas); + } + debugBuf.writeln('--- End of command stream'); + print(debugBuf); + } else { + for (var i = 0; i < _commands.length; i++) { + _commands[i].apply(engineCanvas); + } + } + } + + /// Prints recorded commands. + String debugPrintCommands() { + if (assertionsEnabled) { + final StringBuffer debugBuf = StringBuffer(); + for (var i = 0; i < _commands.length; i++) { + var command = _commands[i]; + debugBuf.writeln('ctx.$command;'); + } + return debugBuf.toString(); + } + return null; + } + + void save() { + _paintBounds.saveTransformsAndClip(); + _commands.add(const PaintSave()); + saveCount++; + } + + void saveLayerWithoutBounds(ui.Paint paint) { + _hasArbitraryPaint = true; + // TODO(het): Implement this correctly using another canvas. + _commands.add(const PaintSave()); + _paintBounds.saveTransformsAndClip(); + saveCount++; + } + + void saveLayer(ui.Rect bounds, ui.Paint paint) { + _hasArbitraryPaint = true; + // TODO(het): Implement this correctly using another canvas. + _commands.add(const PaintSave()); + _paintBounds.saveTransformsAndClip(); + saveCount++; + } + + void restore() { + _paintBounds.restoreTransformsAndClip(); + if (_commands.isNotEmpty && _commands.last is PaintSave) { + // A restore followed a save without any drawing operations in between. + // This means that the save didn't have any effect on drawing operations + // and can be omitted. This makes our communication with the canvas less + // chatty. + _commands.removeLast(); + } else { + _commands.add(const PaintRestore()); + } + saveCount--; + } + + void translate(double dx, double dy) { + _paintBounds.translate(dx, dy); + _commands.add(new PaintTranslate(dx, dy)); + } + + void scale(double sx, double sy) { + _paintBounds.scale(sx, sy); + _commands.add(new PaintScale(sx, sy)); + } + + void rotate(double radians) { + _paintBounds.rotateZ(radians); + _commands.add(new PaintRotate(radians)); + } + + void transform(Float64List matrix4) { + _paintBounds.transform(matrix4); + _commands.add(new PaintTransform(matrix4)); + } + + void skew(double sx, double sy) { + _hasArbitraryPaint = true; + _paintBounds.skew(sx, sy); + _commands.add(new PaintSkew(sx, sy)); + } + + void clipRect(ui.Rect rect) { + _paintBounds.clipRect(rect); + _hasArbitraryPaint = true; + _commands.add(new PaintClipRect(rect)); + } + + void clipRRect(ui.RRect rrect) { + _paintBounds.clipRect(rrect.outerRect); + _hasArbitraryPaint = true; + _commands.add(new PaintClipRRect(rrect)); + } + + void clipPath(ui.Path path) { + _paintBounds.clipRect(path.getBounds()); + _hasArbitraryPaint = true; + _commands.add(new PaintClipPath(path)); + } + + void drawColor(ui.Color color, ui.BlendMode blendMode) { + _hasArbitraryPaint = true; + _didDraw = true; + _paintBounds.grow(_paintBounds.maxPaintBounds); + _commands.add(new PaintDrawColor(color, blendMode)); + } + + void drawLine(ui.Offset p1, ui.Offset p2, ui.Paint paint) { + final double strokeWidth = math.max(paint.strokeWidth, 1.0); + // TODO(yjbanov): This can be optimized. Currently we create a box around + // the line and then apply the transform on the box to get + // the bounding box. If you have a 45-degree line and a + // 45-degree transform, the bounding box should be the length + // of the line long and stroke width wide, but our current + // algorithm produces a square with each side of the length + // matching the length of the line. + _paintBounds.growLTRB( + math.min(p1.dx, p2.dx) - strokeWidth, + math.min(p1.dy, p2.dy) - strokeWidth, + math.max(p1.dx, p2.dx) + strokeWidth, + math.max(p1.dy, p2.dy) + strokeWidth); + _hasArbitraryPaint = true; + _didDraw = true; + _commands.add(new PaintDrawLine(p1, p2, paint.webOnlyPaintData)); + } + + void drawPaint(ui.Paint paint) { + _hasArbitraryPaint = true; + _didDraw = true; + _paintBounds.grow(_paintBounds.maxPaintBounds); + _commands.add(new PaintDrawPaint(paint.webOnlyPaintData)); + } + + void drawRect(ui.Rect rect, ui.Paint paint) { + if (paint.shader != null) { + _hasArbitraryPaint = true; + } + _didDraw = true; + if (paint.strokeWidth != null && paint.strokeWidth != 0) { + _paintBounds.grow(rect.inflate(paint.strokeWidth / 2.0)); + } else { + _paintBounds.grow(rect); + } + _commands.add(new PaintDrawRect(rect, paint.webOnlyPaintData)); + } + + void drawRRect(ui.RRect rrect, ui.Paint paint) { + _hasArbitraryPaint = true; + _didDraw = true; + var strokeWidth = paint.strokeWidth == null ? 0 : paint.strokeWidth; + var left = math.min(rrect.left, rrect.right) - strokeWidth; + var right = math.max(rrect.left, rrect.right) + strokeWidth; + var top = math.min(rrect.top, rrect.bottom) - strokeWidth; + var bottom = math.max(rrect.top, rrect.bottom) + strokeWidth; + _paintBounds.growLTRB(left, top, right, bottom); + _commands.add(new PaintDrawRRect(rrect, paint.webOnlyPaintData)); + } + + void drawDRRect(ui.RRect outer, ui.RRect inner, ui.Paint paint) { + // If inner rect is not contained inside outer, flutter engine skips + // painting rectangle. + if (!(outer.contains(ui.Offset(inner.left, inner.top)) && + outer.contains(ui.Offset(inner.right, inner.bottom)))) { + return; + } + _hasArbitraryPaint = true; + _didDraw = true; + var strokeWidth = paint.strokeWidth == null ? 0 : paint.strokeWidth; + _paintBounds.growLTRB(outer.left - strokeWidth, outer.top - strokeWidth, + outer.right + strokeWidth, outer.bottom + strokeWidth); + _commands.add(new PaintDrawDRRect(outer, inner, paint.webOnlyPaintData)); + } + + void drawOval(ui.Rect rect, ui.Paint paint) { + _hasArbitraryPaint = true; + _didDraw = true; + if (paint.strokeWidth != null) { + _paintBounds.grow(rect.inflate(paint.strokeWidth)); + } else { + _paintBounds.grow(rect); + } + _commands.add(new PaintDrawOval(rect, paint.webOnlyPaintData)); + } + + void drawCircle(ui.Offset c, double radius, ui.Paint paint) { + _hasArbitraryPaint = true; + _didDraw = true; + var strokeWidth = paint.strokeWidth == null ? 0 : paint.strokeWidth; + _paintBounds.growLTRB( + c.dx - radius - strokeWidth, + c.dy - radius - strokeWidth, + c.dx + radius + strokeWidth, + c.dy + radius + strokeWidth); + _commands.add(new PaintDrawCircle(c, radius, paint.webOnlyPaintData)); + } + + void drawPath(ui.Path path, ui.Paint paint) { + _hasArbitraryPaint = true; + _didDraw = true; + ui.Rect pathBounds = path.getBounds(); + if (paint.strokeWidth != null) { + pathBounds = pathBounds.inflate(paint.strokeWidth); + } + _paintBounds.grow(pathBounds); + _commands.add(new PaintDrawPath(path, paint.webOnlyPaintData)); + } + + void drawImage(ui.Image image, ui.Offset offset, ui.Paint paint) { + _hasArbitraryPaint = true; + _didDraw = true; + var left = offset.dx; + var top = offset.dy; + _paintBounds.growLTRB(left, top, left + image.width, top + image.height); + _commands.add(new PaintDrawImage(image, offset, paint.webOnlyPaintData)); + } + + void drawImageRect(ui.Image image, ui.Rect src, ui.Rect dst, ui.Paint paint) { + _hasArbitraryPaint = true; + _didDraw = true; + _paintBounds.grow(dst); + _commands + .add(new PaintDrawImageRect(image, src, dst, paint.webOnlyPaintData)); + } + + void drawParagraph(ui.Paragraph paragraph, ui.Offset offset) { + _didDraw = true; + var left = offset.dx; + var top = offset.dy; + _paintBounds.growLTRB( + left, top, left + paragraph.width, top + paragraph.height); + _commands.add(new PaintDrawParagraph(paragraph, offset)); + } + + void drawShadow(ui.Path path, ui.Color color, double elevation, + bool transparentOccluder) { + _hasArbitraryPaint = true; + _didDraw = true; + ui.Rect shadowRect = + ElevationShadow.computeShadowRect(path.getBounds(), elevation); + _paintBounds.grow(shadowRect); + _commands + .add(new PaintDrawShadow(path, color, elevation, transparentOccluder)); + } + + int saveCount = 1; + + /// Prints the commands recorded by this canvas to the console. + void debugDumpCommands() { + print('/' * 40 + ' CANVAS COMMANDS ' + '/' * 40); + for (final command in _commands) { + print(command); + } + print('/' * 37 + ' END OF CANVAS COMMANDS ' + '/' * 36); + } +} + +abstract class PaintCommand { + const PaintCommand(); + + void apply(EngineCanvas canvas); + + void serializeToCssPaint(List serializedCommands); +} + +class PaintSave extends PaintCommand { + const PaintSave(); + + @override + void apply(EngineCanvas canvas) { + canvas.save(); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'save()'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add(const [1]); + } +} + +class PaintRestore extends PaintCommand { + const PaintRestore(); + + @override + void apply(EngineCanvas canvas) { + canvas.restore(); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'restore()'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add(const [2]); + } +} + +class PaintTranslate extends PaintCommand { + final double dx; + final double dy; + + PaintTranslate(this.dx, this.dy); + + @override + void apply(EngineCanvas canvas) { + canvas.translate(dx, dy); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'translate($dx, $dy)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([3, dx, dy]); + } +} + +class PaintScale extends PaintCommand { + final double sx; + final double sy; + + PaintScale(this.sx, this.sy); + + @override + void apply(EngineCanvas canvas) { + canvas.scale(sx, sy); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'scale($sx, $sy)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([4, sx, sy]); + } +} + +class PaintRotate extends PaintCommand { + final double radians; + + PaintRotate(this.radians); + + @override + void apply(EngineCanvas canvas) { + canvas.rotate(radians); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'rotate($radians)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([5, radians]); + } +} + +class PaintTransform extends PaintCommand { + final Float64List matrix4; + + PaintTransform(this.matrix4); + + @override + void apply(EngineCanvas canvas) { + canvas.transform(matrix4); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'transform(Matrix4.fromFloat64List(Float64List.fromList([${matrix4.join(', ')}])))'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([6]..addAll(matrix4)); + } +} + +class PaintSkew extends PaintCommand { + final double sx; + final double sy; + + PaintSkew(this.sx, this.sy); + + @override + void apply(EngineCanvas canvas) { + canvas.skew(sx, sy); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'skew($sx, $sy)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([7, sx, sy]); + } +} + +class PaintClipRect extends PaintCommand { + final ui.Rect rect; + + PaintClipRect(this.rect); + + @override + void apply(EngineCanvas canvas) { + canvas.clipRect(rect); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'clipRect($rect)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([8, _serializeRectToCssPaint(rect)]); + } +} + +class PaintClipRRect extends PaintCommand { + final ui.RRect rrect; + + PaintClipRRect(this.rrect); + + @override + void apply(EngineCanvas canvas) { + canvas.clipRRect(rrect); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'clipRRect($rrect)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([ + 9, + _serializeRRectToCssPaint(rrect), + ]); + } +} + +class PaintClipPath extends PaintCommand { + final ui.Path path; + + PaintClipPath(this.path); + + @override + void apply(EngineCanvas canvas) { + canvas.clipPath(path); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'clipPath($path)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([10, path.webOnlySerializeToCssPaint()]); + } +} + +class PaintDrawColor extends PaintCommand { + final ui.Color color; + final ui.BlendMode blendMode; + + PaintDrawColor(this.color, this.blendMode); + + @override + void apply(EngineCanvas canvas) { + canvas.drawColor(color, blendMode); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawColor($color, $blendMode)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([11, color.toCssString(), blendMode.index]); + } +} + +class PaintDrawLine extends PaintCommand { + final ui.Offset p1; + final ui.Offset p2; + final ui.PaintData paint; + + PaintDrawLine(this.p1, this.p2, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawLine(p1, p2, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawLine($p1, $p2, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add( + [12, p1.dx, p1.dy, p2.dx, p2.dy, _serializePaintToCssPaint(paint)]); + } +} + +class PaintDrawPaint extends PaintCommand { + final ui.PaintData paint; + + PaintDrawPaint(this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawPaint(paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawPaint($paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([13, _serializePaintToCssPaint(paint)]); + } +} + +class PaintDrawRect extends PaintCommand { + final ui.Rect rect; + final ui.PaintData paint; + + PaintDrawRect(this.rect, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawRect(rect, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawRect($rect, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add( + [14, _serializeRectToCssPaint(rect), _serializePaintToCssPaint(paint)]); + } +} + +class PaintDrawRRect extends PaintCommand { + final ui.RRect rrect; + final ui.PaintData paint; + + PaintDrawRRect(this.rrect, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawRRect(rrect, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawRRect($rrect, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([ + 15, + _serializeRRectToCssPaint(rrect), + _serializePaintToCssPaint(paint), + ]); + } +} + +class PaintDrawDRRect extends PaintCommand { + final ui.RRect outer; + final ui.RRect inner; + final ui.PaintData paint; + + PaintDrawDRRect(this.outer, this.inner, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawDRRect(outer, inner, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawDRRect($outer, $inner, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([ + 16, + _serializeRRectToCssPaint(outer), + _serializeRRectToCssPaint(inner), + _serializePaintToCssPaint(paint), + ]); + } +} + +class PaintDrawOval extends PaintCommand { + final ui.Rect rect; + final ui.PaintData paint; + + PaintDrawOval(this.rect, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawOval(rect, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawOval($rect, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([ + 17, + _serializeRectToCssPaint(rect), + _serializePaintToCssPaint(paint), + ]); + } +} + +class PaintDrawCircle extends PaintCommand { + final ui.Offset c; + final double radius; + final ui.PaintData paint; + + PaintDrawCircle(this.c, this.radius, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawCircle(c, radius, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawCircle($c, $radius, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([ + 18, + c.dx, + c.dy, + radius, + _serializePaintToCssPaint(paint), + ]); + } +} + +class PaintDrawPath extends PaintCommand { + final ui.Path path; + final ui.PaintData paint; + + PaintDrawPath(this.path, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawPath(path, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawPath($path, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([ + 19, + path.webOnlySerializeToCssPaint(), + _serializePaintToCssPaint(paint), + ]); + } +} + +class PaintDrawShadow extends PaintCommand { + PaintDrawShadow( + this.path, this.color, this.elevation, this.transparentOccluder); + + final ui.Path path; + final ui.Color color; + final double elevation; + final bool transparentOccluder; + + @override + void apply(EngineCanvas canvas) { + canvas.drawShadow(path, color, elevation, transparentOccluder); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawShadow($path, $color, $elevation, $transparentOccluder)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + serializedCommands.add([ + 20, + path.webOnlySerializeToCssPaint(), + [ + color.alpha, + color.red, + color.green, + color.blue, + ], + elevation, + transparentOccluder, + ]); + } +} + +class PaintDrawImage extends PaintCommand { + final ui.Image image; + final ui.Offset offset; + final ui.PaintData paint; + + PaintDrawImage(this.image, this.offset, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawImage(image, offset, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawImage($image, $offset, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + if (assertionsEnabled) { + throw UnsupportedError('drawImage not serializable'); + } + } +} + +class PaintDrawImageRect extends PaintCommand { + final ui.Image image; + final ui.Rect src; + final ui.Rect dst; + final ui.PaintData paint; + + PaintDrawImageRect(this.image, this.src, this.dst, this.paint); + + @override + void apply(EngineCanvas canvas) { + canvas.drawImageRect(image, src, dst, paint); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'drawImageRect($image, $src, $dst, $paint)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + if (assertionsEnabled) { + throw UnsupportedError('drawImageRect not serializable'); + } + } +} + +class PaintDrawParagraph extends PaintCommand { + final ui.Paragraph paragraph; + final ui.Offset offset; + + PaintDrawParagraph(this.paragraph, this.offset); + + @override + void apply(EngineCanvas canvas) { + if (!paragraph.webOnlyIsLaidOut) { + // Ignore non-laid out paragraphs. This matches Flutter's behavior. + return; + } + + canvas.drawParagraph(paragraph, offset); + } + + @override + String toString() { + if (assertionsEnabled) { + return 'DrawParagraph(${paragraph.webOnlyGetPlainText()}, $offset)'; + } else { + return super.toString(); + } + } + + void serializeToCssPaint(List serializedCommands) { + if (assertionsEnabled) { + throw UnsupportedError('drawParagraph not serializable'); + } + } +} + +List _serializePaintToCssPaint(ui.PaintData paint) { + return [ + paint.blendMode?.index, + paint.style?.index, + paint.strokeWidth, + paint.strokeCap?.index, + paint.isAntiAlias, + paint.color.toCssString(), + paint.shader?.webOnlySerializeToCssPaint(), + paint.maskFilter?.webOnlySerializeToCssPaint(), + paint.filterQuality?.index, + paint.colorFilter?.webOnlySerializeToCssPaint(), + ]; +} + +List _serializeRectToCssPaint(ui.Rect rect) { + return [ + rect.left, + rect.top, + rect.right, + rect.bottom, + ]; +} + +List _serializeRRectToCssPaint(ui.RRect rrect) { + return [ + rrect.left, + rrect.top, + rrect.right, + rrect.bottom, + rrect.tlRadiusX, + rrect.tlRadiusY, + rrect.trRadiusX, + rrect.trRadiusY, + rrect.brRadiusX, + rrect.brRadiusY, + rrect.blRadiusX, + rrect.blRadiusY, + ]; +} + +class Subpath { + double startX = 0.0; + double startY = 0.0; + double currentX = 0.0; + double currentY = 0.0; + + final List commands; + + Subpath(this.startX, this.startY) : commands = []; + + Subpath shift(ui.Offset offset) { + final result = Subpath(startX + offset.dx, startY + offset.dy) + ..currentX = currentX + offset.dx + ..currentY = currentY + offset.dy; + + for (final command in commands) { + result.commands.add(command.shifted(offset)); + } + + return result; + } + + List serializeToCssPaint() { + final List serialization = []; + for (int i = 0; i < commands.length; i++) { + serialization.add(commands[i].serializeToCssPaint()); + } + return serialization; + } + + @override + String toString() { + if (assertionsEnabled) { + return 'Subpath(${commands.join(', ')})'; + } else { + return super.toString(); + } + } +} + +/// ! Houdini implementation relies on indices here. Keep in sync. +class PathCommandTypes { + static const moveTo = 0; + static const lineTo = 1; + static const ellipse = 2; + static const close = 3; + static const quadraticCurveTo = 4; + static const bezierCurveTo = 5; + static const rect = 6; + static const rRect = 7; +} + +abstract class PathCommand { + final int type; + const PathCommand(this.type); + + PathCommand shifted(ui.Offset offset); + + List serializeToCssPaint(); +} + +class MoveTo extends PathCommand { + final double x; + final double y; + + const MoveTo(this.x, this.y) : super(PathCommandTypes.moveTo); + + @override + MoveTo shifted(ui.Offset offset) { + return new MoveTo(x + offset.dx, y + offset.dy); + } + + @override + List serializeToCssPaint() { + return [1, x, y]; + } + + @override + String toString() { + if (assertionsEnabled) { + return 'MoveTo($x, $y)'; + } else { + return super.toString(); + } + } +} + +class LineTo extends PathCommand { + final double x; + final double y; + + const LineTo(this.x, this.y) : super(PathCommandTypes.lineTo); + + @override + LineTo shifted(ui.Offset offset) { + return new LineTo(x + offset.dx, y + offset.dy); + } + + @override + List serializeToCssPaint() { + return [2, x, y]; + } + + @override + String toString() { + if (assertionsEnabled) { + return 'LineTo($x, $y)'; + } else { + return super.toString(); + } + } +} + +class Ellipse extends PathCommand { + final double x; + final double y; + final double radiusX; + final double radiusY; + final double rotation; + final double startAngle; + final double endAngle; + final bool anticlockwise; + + const Ellipse(this.x, this.y, this.radiusX, this.radiusY, this.rotation, + this.startAngle, this.endAngle, this.anticlockwise) + : super(PathCommandTypes.ellipse); + + @override + Ellipse shifted(ui.Offset offset) { + return new Ellipse(x + offset.dx, y + offset.dy, radiusX, radiusY, rotation, + startAngle, endAngle, anticlockwise); + } + + @override + List serializeToCssPaint() { + return [ + 3, + x, + y, + radiusX, + radiusY, + rotation, + startAngle, + endAngle, + anticlockwise, + ]; + } + + @override + String toString() { + if (assertionsEnabled) { + return 'Ellipse($x, $y, $radiusX, $radiusY)'; + } else { + return super.toString(); + } + } +} + +class QuadraticCurveTo extends PathCommand { + final double x1; + final double y1; + final double x2; + final double y2; + + const QuadraticCurveTo(this.x1, this.y1, this.x2, this.y2) + : super(PathCommandTypes.quadraticCurveTo); + + @override + QuadraticCurveTo shifted(ui.Offset offset) { + return new QuadraticCurveTo( + x1 + offset.dx, y1 + offset.dy, x2 + offset.dx, y2 + offset.dy); + } + + @override + List serializeToCssPaint() { + return [4, x1, y1, x2, y2]; + } + + @override + String toString() { + if (assertionsEnabled) { + return 'QuadraticCurveTo($x1, $y1, $x2, $y2)'; + } else { + return super.toString(); + } + } +} + +class BezierCurveTo extends PathCommand { + final double x1; + final double y1; + final double x2; + final double y2; + final double x3; + final double y3; + + const BezierCurveTo(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3) + : super(PathCommandTypes.bezierCurveTo); + + @override + BezierCurveTo shifted(ui.Offset offset) { + return new BezierCurveTo(x1 + offset.dx, y1 + offset.dy, x2 + offset.dx, + y2 + offset.dy, x3 + offset.dx, y3 + offset.dy); + } + + @override + List serializeToCssPaint() { + return [5, x1, y1, x2, y2, x3, y3]; + } + + @override + String toString() { + if (assertionsEnabled) { + return 'BezierCurveTo($x1, $y1, $x2, $y2, $x3, $y3)'; + } else { + return super.toString(); + } + } +} + +class RectCommand extends PathCommand { + final double x; + final double y; + final double width; + final double height; + + const RectCommand(this.x, this.y, this.width, this.height) + : super(PathCommandTypes.rect); + + @override + RectCommand shifted(ui.Offset offset) { + return new RectCommand(x + offset.dx, y + offset.dy, width, height); + } + + @override + List serializeToCssPaint() { + return [6, x, y, width, height]; + } + + @override + String toString() { + if (assertionsEnabled) { + return 'Rect($x, $y, $width, $height)'; + } else { + return super.toString(); + } + } +} + +class RRectCommand extends PathCommand { + final ui.RRect rrect; + + const RRectCommand(this.rrect) : super(PathCommandTypes.rRect); + + @override + RRectCommand shifted(ui.Offset offset) { + return new RRectCommand(rrect.shift(offset)); + } + + @override + List serializeToCssPaint() { + return [7, _serializeRRectToCssPaint(rrect)]; + } + + @override + String toString() { + if (assertionsEnabled) { + return '$rrect'; + } else { + return super.toString(); + } + } +} + +class CloseCommand extends PathCommand { + const CloseCommand() : super(PathCommandTypes.close); + + @override + CloseCommand shifted(ui.Offset offset) { + return this; + } + + @override + List serializeToCssPaint() { + return [8]; + } + + @override + String toString() { + if (assertionsEnabled) { + return 'Close()'; + } else { + return super.toString(); + } + } +} + +class _PaintBounds { + // Bounds of maximum area that is paintable by canvas ops. + final ui.Rect maxPaintBounds; + + bool _didPaintInsideClipArea = false; + // Bounds of actually painted area. If _left is not set, reported paintBounds + // should be empty since growLTRB calls were outside active clipping + // region. + double _left, _top, _right, _bottom; + // Stack of transforms. + List _transforms; + // Stack of clip bounds. + List _clipStack; + bool _currentMatrixIsIdentity = true; + Matrix4 _currentMatrix = Matrix4.identity(); + bool _clipRectInitialized = false; + double _currentClipLeft = 0.0, + _currentClipTop = 0.0, + _currentClipRight = 0.0, + _currentClipBottom = 0.0; + + _PaintBounds(this.maxPaintBounds); + + void translate(double dx, double dy) { + if (dx != 0.0 || dy != 0.0) _currentMatrixIsIdentity = false; + _currentMatrix.translate(dx, dy); + } + + void scale(double sx, double sy) { + if (sx != 1.0 || sy != 1.0) _currentMatrixIsIdentity = false; + _currentMatrix.scale(sx, sy); + } + + void rotateZ(double radians) { + if (radians != 0.0) _currentMatrixIsIdentity = false; + _currentMatrix.rotateZ(radians); + } + + void transform(Float64List matrix4) { + var m4 = new Matrix4.fromFloat64List(matrix4); + _currentMatrix.multiply(m4); + _currentMatrixIsIdentity = _currentMatrix.isIdentity(); + } + + void skew(double sx, double sy) { + _currentMatrixIsIdentity = false; + + // DO NOT USE Matrix4.skew(sx, sy)! It treats sx and sy values as radians, + // but in our case they are transform matrix values. + final Matrix4 skewMatrix = Matrix4.identity(); + final Float64List storage = skewMatrix.storage; + storage[1] = sy; + storage[4] = sx; + _currentMatrix.multiply(skewMatrix); + } + + void clipRect(ui.Rect rect) { + // If we have an active transform, calculate screen relative clipping + // rectangle and union with current clipping rectangle. + if (!_currentMatrixIsIdentity) { + Vector3 leftTop = + _currentMatrix.transform3(Vector3(rect.left, rect.top, 0.0)); + Vector3 rightTop = + _currentMatrix.transform3(Vector3(rect.right, rect.top, 0.0)); + Vector3 leftBottom = + _currentMatrix.transform3(Vector3(rect.left, rect.bottom, 0.0)); + Vector3 rightBottom = + _currentMatrix.transform3(Vector3(rect.right, rect.bottom, 0.0)); + rect = ui.Rect.fromLTRB( + math.min(math.min(math.min(leftTop.x, rightTop.x), leftBottom.x), + rightBottom.x), + math.min(math.min(math.min(leftTop.y, rightTop.y), leftBottom.y), + rightBottom.y), + math.max(math.max(math.max(leftTop.x, rightTop.x), leftBottom.x), + rightBottom.x), + math.max(math.max(math.max(leftTop.y, rightTop.y), leftBottom.y), + rightBottom.y)); + } + if (!_clipRectInitialized) { + _currentClipLeft = rect.left; + _currentClipTop = rect.top; + _currentClipRight = rect.right; + _currentClipBottom = rect.bottom; + _clipRectInitialized = true; + } else { + if (rect.left > _currentClipLeft) _currentClipLeft = rect.left; + if (rect.top > _currentClipTop) _currentClipTop = rect.top; + if (rect.right < _currentClipRight) { + _currentClipRight = rect.right; + } + if (rect.bottom < _currentClipBottom) _currentClipBottom = rect.bottom; + } + } + + /// Grow painted area to include given rectangle. + void grow(ui.Rect r) { + growLTRB(r.left, r.top, r.right, r.bottom); + } + + /// Grow painted area to include given rectangle. + void growLTRB(double left, double top, double right, double bottom) { + if (left == right || top == bottom) return; + + var transformedPointLeft = left; + var transformedPointTop = top; + var transformedPointRight = right; + var transformedPointBottom = bottom; + + if (!_currentMatrixIsIdentity) { + ui.Rect transformedRect = localClipToGlobalClip( + localLeft: left, + localTop: top, + localRight: right, + localBottom: bottom, + transform: _currentMatrix, + ); + transformedPointLeft = transformedRect.left; + transformedPointTop = transformedRect.top; + transformedPointRight = transformedRect.right; + transformedPointBottom = transformedRect.bottom; + } + + if (_clipRectInitialized) { + if (transformedPointLeft > _currentClipRight) return; + if (transformedPointRight < _currentClipLeft) return; + if (transformedPointTop > _currentClipBottom) return; + if (transformedPointBottom < _currentClipTop) return; + if (transformedPointLeft < _currentClipLeft) { + transformedPointLeft = _currentClipLeft; + } + if (transformedPointRight > _currentClipRight) { + transformedPointRight = _currentClipRight; + } + if (transformedPointTop < _currentClipTop) { + transformedPointTop = _currentClipTop; + } + if (transformedPointBottom > _currentClipBottom) { + transformedPointBottom = _currentClipBottom; + } + } + + if (_didPaintInsideClipArea) { + _left = math.min( + math.min(_left, transformedPointLeft), transformedPointRight); + _right = math.max( + math.max(_right, transformedPointLeft), transformedPointRight); + _top = + math.min(math.min(_top, transformedPointTop), transformedPointBottom); + _bottom = math.max( + math.max(_bottom, transformedPointTop), transformedPointBottom); + } else { + _left = math.min(transformedPointLeft, transformedPointRight); + _right = math.max(transformedPointLeft, transformedPointRight); + _top = math.min(transformedPointTop, transformedPointBottom); + _bottom = math.max(transformedPointTop, transformedPointBottom); + } + _didPaintInsideClipArea = true; + } + + void saveTransformsAndClip() { + _clipStack ??= []; + _transforms ??= []; + _transforms.add(_currentMatrix?.clone()); + _clipStack.add(_clipRectInitialized + ? new ui.Rect.fromLTRB(_currentClipLeft, _currentClipTop, + _currentClipRight, _currentClipBottom) + : null); + } + + void restoreTransformsAndClip() { + _currentMatrix = _transforms.removeLast(); + ui.Rect clipRect = _clipStack.removeLast(); + if (clipRect != null) { + _currentClipLeft = clipRect.left; + _currentClipTop = clipRect.top; + _currentClipRight = clipRect.right; + _currentClipBottom = clipRect.bottom; + _clipRectInitialized = true; + } else if (_clipRectInitialized) { + _clipRectInitialized = false; + } + } + + ui.Rect computeBounds() { + if (!_didPaintInsideClipArea) return ui.Rect.zero; + + // The framework may send us NaNs in the case when it attempts to invert an + // infinitely size rect. + final double maxLeft = maxPaintBounds.left.isNaN + ? double.negativeInfinity + : maxPaintBounds.left; + final double maxRight = + maxPaintBounds.right.isNaN ? double.infinity : maxPaintBounds.right; + final double maxTop = + maxPaintBounds.top.isNaN ? double.negativeInfinity : maxPaintBounds.top; + final double maxBottom = + maxPaintBounds.bottom.isNaN ? double.infinity : maxPaintBounds.bottom; + + final double left = math.min(_left, _right); + final double right = math.max(_left, _right); + final double top = math.min(_top, _bottom); + final double bottom = math.max(_top, _bottom); + + if (right < maxLeft || bottom < maxTop) { + // Computed and max bounds do not intersect. + return ui.Rect.zero; + } + + return ui.Rect.fromLTRB( + math.max(left, maxLeft), + math.max(top, maxTop), + math.min(right, maxRight), + math.min(bottom, maxBottom), + ); + } + + @override + String toString() { + if (assertionsEnabled) { + final ui.Rect bounds = computeBounds(); + return '_PaintBounds(${bounds} of size ${bounds.size})'; + } else { + return super.toString(); + } + } +} diff --git a/lib/stub_ui/lib/src/engine/semantics/checkable.dart b/lib/stub_ui/lib/src/engine/semantics/checkable.dart new file mode 100644 index 0000000000000..5846685e79f4e --- /dev/null +++ b/lib/stub_ui/lib/src/engine/semantics/checkable.dart @@ -0,0 +1,71 @@ +// 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. + +// TODO(yjbanov): TalkBack on Android incorrectly reads state changes for radio +// buttons. When checking a radio button it reads +// "Checked, not checked". This is likely due to another radio +// button automatically becoming unchecked. VoiceOver reads it +// correctly. It is possible we can fix this by using +// "radiogroup" and "aria-owns". This may require a change in the +// framework. Currently the framework does not report the +// grouping of radio buttons. + +part of engine; + +/// The specific type of checkable control. +enum _CheckableKind { + /// A checkbox. + checkbox, + + /// A radio button, defined by [ui.SemanticsFlag.isInMutuallyExclusiveGroup]. + radio, +} + +/// Renders semantics objects that have checked state. +/// +/// See also [ui.SemanticsFlag.hasCheckedState], [ui.SemanticsFlag.isChecked], +/// and [ui.SemanticsFlag.isInMutuallyExclusiveGroup]. +class Checkable extends RoleManager { + _CheckableKind _kind; + + Checkable(SemanticsObject semanticsObject) + : super(Role.checkable, semanticsObject) { + if (semanticsObject.hasFlag(ui.SemanticsFlag.isInMutuallyExclusiveGroup)) { + _kind = _CheckableKind.radio; + } else { + _kind = _CheckableKind.checkbox; + } + } + + @override + void update() { + if (semanticsObject.isFlagsDirty) { + switch (_kind) { + case _CheckableKind.checkbox: + semanticsObject.setAriaRole('checkbox', true); + break; + case _CheckableKind.radio: + semanticsObject.setAriaRole('radio', true); + break; + } + + semanticsObject.element.setAttribute( + 'aria-checked', + semanticsObject.hasFlag(ui.SemanticsFlag.isChecked) ? 'true' : 'false', + ); + } + } + + @override + void dispose() { + switch (_kind) { + case _CheckableKind.checkbox: + semanticsObject.setAriaRole('checkbox', false); + break; + case _CheckableKind.radio: + semanticsObject.setAriaRole('radio', false); + break; + } + } +} diff --git a/lib/stub_ui/lib/src/engine/semantics/incrementable.dart b/lib/stub_ui/lib/src/engine/semantics/incrementable.dart new file mode 100644 index 0000000000000..0e3780e5aaefe --- /dev/null +++ b/lib/stub_ui/lib/src/engine/semantics/incrementable.dart @@ -0,0 +1,140 @@ +// 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. + +part of engine; + +/// Adds increment/decrement event handling to a semantics object. +/// +/// The implementation uses a hidden `` element with ARIA +/// attributes to cause the browser to render increment/decrement controls to +/// the assistive technology. +/// +/// The input element is disabled whenever the gesture mode switches to pointer +/// events. This is to prevent the browser from taking over drag gestures. Drag +/// gestures must be interpreted by the Flutter framework. +class Incrementable extends RoleManager { + /// The HTML element used to render semantics to the browser. + final html.InputElement _element = html.InputElement(); + + /// The value used by the input element. + /// + /// Flutter values are strings, and are not necessarily numbers. In order to + /// convey to the browser what the available "range" of values is we + /// substitute the framework value with a generated `int` surrogate. + /// "aria-valuetext" attribute is used to cause the browser to announce the + /// framework value to the user. + int _currentSurrogateValue = 1; + + /// Disables the input [_element] when the gesture mode switches to + /// [GestureMode.pointerEvents], and enables it when the mode switches back to + /// [GestureMode.browserGestures]. + GestureModeCallback _gestureModeListener; + + /// Whether we forwarded a semantics action to the framework and awaiting an + /// update. + /// + /// This field is used to determine whether the HTML DOM of the semantics + /// tree should be updated. + bool _pendingResync = false; + + Incrementable(SemanticsObject semanticsObject) + : super(Role.incrementable, semanticsObject) { + semanticsObject.element.append(_element); + _element.type = 'range'; + _element.setAttribute('role', 'slider'); + + _element.addEventListener('change', (_) { + if (_element.disabled) { + return; + } + _pendingResync = true; + final int newInputValue = int.parse(_element.value); + if (newInputValue > _currentSurrogateValue) { + _currentSurrogateValue += 1; + ui.window.onSemanticsAction( + semanticsObject.id, ui.SemanticsAction.increase, null); + } else if (newInputValue < _currentSurrogateValue) { + _currentSurrogateValue -= 1; + ui.window.onSemanticsAction( + semanticsObject.id, ui.SemanticsAction.decrease, null); + } + }); + + // Store the callback as a closure because Dart does not guarantee that + // tear-offs produce the same function object. + _gestureModeListener = (GestureMode mode) { + update(); + }; + semanticsObject.owner.addGestureModeListener(_gestureModeListener); + } + + @override + void update() { + switch (semanticsObject.owner.gestureMode) { + case GestureMode.browserGestures: + _enableBrowserGestureHandling(); + _updateInputValues(); + break; + case GestureMode.pointerEvents: + _disableBrowserGestureHandling(); + break; + } + } + + void _enableBrowserGestureHandling() { + assert(semanticsObject.owner.gestureMode == GestureMode.browserGestures); + if (!_element.disabled) { + return; + } + _element.disabled = false; + } + + void _updateInputValues() { + assert(semanticsObject.owner.gestureMode == GestureMode.browserGestures); + + final bool updateNeeded = _pendingResync || + semanticsObject.isValueDirty || + semanticsObject.isIncreasedValueDirty || + semanticsObject.isDecreasedValueDirty; + + if (!updateNeeded) { + return; + } + + _pendingResync = false; + + final String surrogateTextValue = '$_currentSurrogateValue'; + _element.value = surrogateTextValue; + _element.setAttribute('aria-valuenow', surrogateTextValue); + _element.setAttribute('aria-valuetext', semanticsObject.value); + + final bool canIncrease = semanticsObject.increasedValue != null; + final String surrogateMaxTextValue = + canIncrease ? '${_currentSurrogateValue + 1}' : surrogateTextValue; + _element.max = surrogateMaxTextValue; + _element.setAttribute('aria-valuemax', surrogateMaxTextValue); + + final bool canDecrease = semanticsObject.decreasedValue != null; + final String surrogateMinTextValue = + canDecrease ? '${_currentSurrogateValue - 1}' : surrogateTextValue; + _element.min = surrogateMinTextValue; + _element.setAttribute('aria-valuemin', surrogateMinTextValue); + } + + void _disableBrowserGestureHandling() { + if (_element.disabled) { + return; + } + _element.disabled = true; + } + + @override + void dispose() { + assert(_gestureModeListener != null); + semanticsObject.owner.removeGestureModeListener(_gestureModeListener); + _gestureModeListener = null; + _disableBrowserGestureHandling(); + _element.remove(); + } +} diff --git a/lib/stub_ui/lib/src/engine/semantics/label_and_value.dart b/lib/stub_ui/lib/src/engine/semantics/label_and_value.dart new file mode 100644 index 0000000000000..aa8d4748ca7b5 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/semantics/label_and_value.dart @@ -0,0 +1,109 @@ +// 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. + +part of engine; + +/// Renders [_label] and [_value] to the semantics DOM. +/// +/// The rendering method is browser-dependent. There is no explicit ARIA +/// attribute to express "value". Instead, you are expected to render the +/// value as text content of HTML. +/// +/// VoiceOver only supports "aria-label" for certain ARIA roles. For plain +/// text it expects that the label is part of the text content of the element. +/// The strategy for VoiceOver is to combine [_label] and [_value] and stamp +/// out a single child element that contains the value. +/// +/// TalkBack supports the "aria-label" attribute. However, when present, +/// TalkBack ignores the text content. Therefore, we cannot split [_label] +/// and [_value] between "aria-label" and text content. The strategy for +/// TalkBack is to combine [_label] and [_value] into a single "aria-label". +/// +/// The [_value] is not always rendered. Some semantics nodes correspond to +/// interactive controls, such as an `` element. In such case the value +/// is reported via that element's `value` attribute rather than rendering it +/// separately. +class LabelAndValue extends RoleManager { + LabelAndValue(SemanticsObject semanticsObject) + : super(Role.labelAndValue, semanticsObject); + + /// Supplements the "aria-label" that renders the combination of [_label] and + /// [_value] to semantics as text content. + /// + /// This extra element is needed for the following reasons: + /// + /// - VoiceOver on iOS Safari does not recognize standalone "aria-label". It + /// only works for specific roles. + /// - TalkBack does support "aria-label". However, if an element has children + /// its label is not reachable via accessibility focus. This happens, for + /// example in popup dialogs, such as the alert dialog. The text of the + /// alert is supplied as a label on the parent node. + html.Element _auxiliaryValueElement; + + @override + void update() { + final bool hasValue = semanticsObject.hasValue; + final bool hasLabel = semanticsObject.hasLabel; + + // If the node is incrementable or a text field the value is reported to the + // browser via the respective role managers. We do not need to also render + // it again here. + final bool shouldDisplayValue = hasValue && + !semanticsObject.isIncrementable && + !semanticsObject.isTextField; + + if (!hasLabel && !shouldDisplayValue) { + _cleanUpDom(); + return; + } + + final StringBuffer combinedValue = StringBuffer(); + if (hasLabel) { + combinedValue.write(semanticsObject.label); + if (shouldDisplayValue) { + combinedValue.write(' '); + } + } + + if (shouldDisplayValue) { + combinedValue.write(semanticsObject.value); + } + + semanticsObject.element + .setAttribute('aria-label', combinedValue.toString()); + + if (_auxiliaryValueElement == null) { + _auxiliaryValueElement = html.Element.tag('flt-semantics-value'); + // Absolute positioning and sizing of leaf text elements confuses + // VoiceOver. So we let the browser size the value node. The node will + // still have a bigger tap area. However, if the node is a parent to other + // nodes, then VoiceOver behaves as expected with absolute positioning and + // sizing. + if (semanticsObject.hasChildren) { + _auxiliaryValueElement.style + ..position = 'absolute' + ..top = '0' + ..left = '0' + ..width = '${semanticsObject.rect.width}px' + ..height = '${semanticsObject.rect.height}px'; + } + _auxiliaryValueElement.style.fontSize = '6px'; + semanticsObject.element.append(_auxiliaryValueElement); + } + _auxiliaryValueElement.text = combinedValue.toString(); + } + + void _cleanUpDom() { + if (_auxiliaryValueElement != null) { + _auxiliaryValueElement.remove(); + _auxiliaryValueElement = null; + } + semanticsObject.element.attributes.remove('aria-label'); + } + + @override + void dispose() { + _cleanUpDom(); + } +} diff --git a/lib/stub_ui/lib/src/engine/semantics/scrollable.dart b/lib/stub_ui/lib/src/engine/semantics/scrollable.dart new file mode 100644 index 0000000000000..c0898cd939e82 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/semantics/scrollable.dart @@ -0,0 +1,199 @@ +// 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. + +part of engine; + +/// Implements vertical and horizontal scrolling functionality for semantics +/// objects. +/// +/// Scrolling is implemented using a "joystick" method. The absolute value of +/// "scrollTop" in HTML is not important. We only need to know in whether the +/// value changed in the positive or negative direction. If it changes in the +/// positive direction we send a [ui.SemanticsAction.scrollUp]. Otherwise, we +/// send [ui.SemanticsAction.scrollDown]. The actual scrolling is then handled +/// by the framework and we receive a [ui.SemanticsUpdate] containing the new +/// [scrollPosition] and child positions. +/// +/// "scrollTop" or "scrollLeft" is always reset to an arbitrarily chosen non- +/// zero "neutral" scroll position value. This is done so we have a +/// predictable range of DOM scroll position values. When the amount of +/// contents is less than the size of the viewport the browser snaps +/// "scrollTop" back to zero. If there is more content than available in the +/// viewport "scrollTop" may take positive values. +class Scrollable extends RoleManager { + Scrollable(SemanticsObject semanticsObject) + : super(Role.scrollable, semanticsObject); + + /// Disables browser-driven scrolling in the presence of pointer events. + GestureModeCallback _gestureModeListener; + + /// Listens to HTML "scroll" gestures detected by the browser. + /// + /// This gesture is converted to [ui.SemanticsAction.scrollUp] or + /// [ui.SemanticsAction.scrollDown], depending on the direction. + html.EventListener _scrollListener; + + /// The value of the "scrollTop" or "scrollLeft" property of this object's + /// [element] that has zero offset relative to the [scrollPosition]. + int _effectiveNeutralScrollPosition = 0; + + /// Responds to browser-detected "scroll" gestures. + void _recomputeScrollPosition() { + if (_domScrollPosition != _effectiveNeutralScrollPosition) { + if (!semanticsObject.owner.shouldAcceptBrowserGesture('scroll')) { + return; + } + final bool doScrollForward = + _domScrollPosition > _effectiveNeutralScrollPosition; + _neutralizeDomScrollPosition(); + semanticsObject.recomputePositionAndSize(); + + final int semanticsId = semanticsObject.id; + if (doScrollForward) { + if (semanticsObject.isVerticalScrollContainer) { + ui.window.onSemanticsAction( + semanticsId, ui.SemanticsAction.scrollUp, null); + } else { + assert(semanticsObject.isHorizontalScrollContainer); + ui.window.onSemanticsAction( + semanticsId, ui.SemanticsAction.scrollLeft, null); + } + } else { + if (semanticsObject.isVerticalScrollContainer) { + ui.window.onSemanticsAction( + semanticsId, ui.SemanticsAction.scrollDown, null); + } else { + assert(semanticsObject.isHorizontalScrollContainer); + ui.window.onSemanticsAction( + semanticsId, ui.SemanticsAction.scrollRight, null); + } + } + } + } + + @override + void update() { + if (_scrollListener == null) { + // We need to set touch-action:none explicitly here, despite the fact + // that we already have it on the tag because overflow:scroll + // still causes the browser to take over pointer events in order to + // process scrolling. We don't want that when scrolling is handled by + // the framework. + // + // This is effective only in Chrome. Safari does not implement this + // CSS property. In Safari the `PointerBinding` uses `preventDefault` + // to prevent browser scrolling. + semanticsObject.element.style.touchAction = 'none'; + _gestureModeDidChange(); + + // We neutralize the scroll position after all children have been + // updated. Otherwise the browser does not yet have the sizes of the + // child nodes and resets the scrollTop value back to zero. + semanticsObject.owner.addOneTimePostUpdateCallback(() { + _neutralizeDomScrollPosition(); + }); + + // Memoize the tear-off because Dart does not guarantee that two + // tear-offs of a method on the same instance will produce the same + // object. + _gestureModeListener = (_) { + _gestureModeDidChange(); + }; + semanticsObject.owner.addGestureModeListener(_gestureModeListener); + + _scrollListener = (_) { + _recomputeScrollPosition(); + }; + semanticsObject.element.addEventListener('scroll', _scrollListener); + } + } + + /// The value of "scrollTop" or "scrollLeft", depending on the scroll axis. + int get _domScrollPosition { + if (semanticsObject.isVerticalScrollContainer) { + return semanticsObject.element.scrollTop; + } else { + assert(semanticsObject.isHorizontalScrollContainer); + return semanticsObject.element.scrollLeft; + } + } + + /// Resets the scroll position (top or left) to the neutral value. + /// + /// The scroll position of the scrollable HTML node that's considered to + /// have zero offset relative to Flutter's notion of scroll position is + /// referred to as "neutral scroll position". + /// + /// We always set the the scroll position to a non-zero value in order to + /// be able to scroll in the negative direction. When scrollTop/scrollLeft is + /// zero the browser will refuse to scroll back even when there is more + /// content available. + void _neutralizeDomScrollPosition() { + // This value is arbitrary. + const int _canonicalNeutralScrollPosition = 10; + + final html.Element element = semanticsObject.element; + if (semanticsObject.isVerticalScrollContainer) { + element.scrollTop = _canonicalNeutralScrollPosition; + // Read back because the effective value depends on the amount of content. + _effectiveNeutralScrollPosition = element.scrollTop; + semanticsObject + ..verticalContainerAdjustment = + _effectiveNeutralScrollPosition.toDouble() + ..horizontalContainerAdjustment = 0.0; + } else { + element.scrollLeft = _canonicalNeutralScrollPosition; + // Read back because the effective value depends on the amount of content. + _effectiveNeutralScrollPosition = element.scrollLeft; + semanticsObject + ..verticalContainerAdjustment = 0.0 + ..horizontalContainerAdjustment = + _effectiveNeutralScrollPosition.toDouble(); + } + } + + void _gestureModeDidChange() { + final html.Element element = semanticsObject.element; + switch (semanticsObject.owner.gestureMode) { + case GestureMode.browserGestures: + // overflow:scroll will cause the browser report "scroll" events when + // the accessibility focus shifts outside the visible bounds. + // + // Note that on Android overflow:hidden also works. However, we prefer + // "scroll" because it works both on Android and iOS. + if (semanticsObject.isVerticalScrollContainer) { + element.style.overflowY = 'scroll'; + } else { + assert(semanticsObject.isHorizontalScrollContainer); + element.style.overflowX = 'scroll'; + } + break; + case GestureMode.pointerEvents: + // We use "hidden" instead of "scroll" so that the browser does + // not "steal" pointer events. Flutter gesture recognizers need + // all pointer events in order to recognize gestures correctly. + if (semanticsObject.isVerticalScrollContainer) { + element.style.overflowY = 'hidden'; + } else { + assert(semanticsObject.isHorizontalScrollContainer); + element.style.overflowX = 'hidden'; + } + break; + } + } + + @override + void dispose() { + final html.CssStyleDeclaration style = semanticsObject.element.style; + assert(_gestureModeListener != null); + style.removeProperty('overflowY'); + style.removeProperty('overflowX'); + style.removeProperty('touch-action'); + if (_scrollListener != null) { + semanticsObject.element.removeEventListener('scroll', _scrollListener); + } + semanticsObject.owner.removeGestureModeListener(_gestureModeListener); + _gestureModeListener = null; + } +} diff --git a/lib/stub_ui/lib/src/engine/semantics/semantics.dart b/lib/stub_ui/lib/src/engine/semantics/semantics.dart new file mode 100644 index 0000000000000..238deaa2b89d3 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/semantics/semantics.dart @@ -0,0 +1,1680 @@ +// 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. + +part of engine; + +/// Set this flag to `true` to cause the engine to visualize the semantics tree +/// on the screen. +/// +/// This is useful for debugging. +const bool _debugShowSemanticsNodes = false; + +/// Contains updates for the semantics tree. +/// +/// This class provides private engine-side API that's not available in the +/// `dart:ui` [ui.SemanticsUpdate]. +class SemanticsUpdate implements ui.SemanticsUpdate { + SemanticsUpdate({List nodeUpdates}) + : _nodeUpdates = nodeUpdates; + + /// Updates for individual nodes. + final List _nodeUpdates; + + @override + void dispose() { + // Intentionally left blank. This method exists for API compatibility with + // Flutter, but it is not required as memory resource management is handled + // by JavaScript's garbage collector. + } +} + +/// Updates the properties of a particular semantics node. +class SemanticsNodeUpdate { + SemanticsNodeUpdate({ + this.id, + this.flags, + this.actions, + this.textSelectionBase, + this.textSelectionExtent, + this.platformViewId, + this.scrollChildren, + this.scrollIndex, + this.scrollPosition, + this.scrollExtentMax, + this.scrollExtentMin, + this.rect, + this.label, + this.hint, + this.value, + this.increasedValue, + this.decreasedValue, + this.textDirection, + this.transform, + this.elevation, + this.thickness, + this.childrenInTraversalOrder, + this.childrenInHitTestOrder, + this.additionalActions, + }); + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final int id; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final int flags; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final int actions; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final int textSelectionBase; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final int textSelectionExtent; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final int platformViewId; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final int scrollChildren; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final int scrollIndex; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final double scrollPosition; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final double scrollExtentMax; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final double scrollExtentMin; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final ui.Rect rect; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final String label; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final String hint; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final String value; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final String increasedValue; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final String decreasedValue; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final ui.TextDirection textDirection; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final Float64List transform; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final Int32List childrenInTraversalOrder; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final Int32List childrenInHitTestOrder; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final Int32List additionalActions; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final double elevation; + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + final double thickness; +} + +/// Identifies one of the roles a [SemanticsObject] plays. +enum Role { + /// Supports incrementing and/or decrementing its value. + incrementable, + + /// Able to scroll its contents vertically or horizontally. + scrollable, + + /// Contains a label or a value. + /// + /// The two are combined into the same role because they interact with each + /// other. + labelAndValue, + + /// Accepts tap or click gestures. + tappable, + + /// Contains editable text. + textField, + + /// A control that has a checked state, such as a check box or a radio button. + checkable, +} + +/// A function that creates a [RoleManager] for a [SemanticsObject]. +typedef RoleManagerFactory = RoleManager Function(SemanticsObject object); + +final Map _roleFactories = { + Role.incrementable: (SemanticsObject object) => Incrementable(object), + Role.scrollable: (SemanticsObject object) => Scrollable(object), + Role.labelAndValue: (SemanticsObject object) => LabelAndValue(object), + Role.tappable: (SemanticsObject object) => Tappable(object), + Role.textField: (SemanticsObject object) => TextField(object), + Role.checkable: (SemanticsObject object) => Checkable(object), +}; + +/// Provides the functionality associated with the role of the given +/// [semanticsObject]. +/// +/// The role is determined by [ui.SemanticsFlag]s and [ui.SemanticsAction]s set +/// on the object. +abstract class RoleManager { + /// Initializes a role for [semanticsObject]. + /// + /// A single role object manages exactly one [SemanticsObject]. + RoleManager(this.role, this.semanticsObject) + : assert(semanticsObject != null); + + /// Role identifier. + final Role role; + + /// The semantics object managed by this role. + final SemanticsObject semanticsObject; + + /// Called immediately after the [semanticsObject] updates some of its fields. + /// + /// A concrete implementation of this method would typically use some of the + /// "is*Dirty" getters to find out exactly what's changed and apply the + /// minimum DOM updates. + void update(); + + /// Called when [semanticsObject] is removed, or when it changes its role such + /// that this role is no longer relevant. + /// + /// This method is expected to remove role-specific functionality from the + /// DOM. In particular, this method is the appropriate place to call + /// [EngineSemanticsOwner.removeGestureModeListener] if this role reponds to + /// gesture mode changes. + void dispose(); +} + +/// Instantiation of a framework-side semantics node in the DOM. +/// +/// Instances of this class are retained from frame to frame. Each instance is +/// permanently attached to an [id] and a DOM [element] used to convey semantics +/// information to the browser. +class SemanticsObject { + /// Creates a semantics tree node with the given [id] and [owner]. + SemanticsObject(this.id, this.owner) { + // DOM nodes created for semantics objects are positioned absolutely using + // transforms. We use a transparent color instead of "visibility:hidden" or + // "display:none" so that a screen reader does not ignore these elements. + element.style.position = 'absolute'; + + // The root node has some properties that other nodes do not. + if (id == 0) { + // Make all semantics transparent. We use `filter` instead of `opacity` + // attribute because `filter` is stronger. `opacity` does not apply to + // some elements, particularly on iOS, such as the slider thumb and track. + element.style.filter = 'opacity(0%)'; + + // Make text explicitly transparent to signal to the browser that no + // rasterization needs to be done. + element.style.color = 'rgba(0,0,0,0)'; + } + + if (_debugShowSemanticsNodes) { + element.style + ..filter = 'opacity(90%)' + ..outline = '1px solid green' + ..color = 'purple'; + } + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + int get flags => _flags; + int _flags; + + /// Whether the [flags] field has been updated but has not been applied to the + /// DOM yet. + bool get isFlagsDirty => _isDirty(_flagsIndex); + static const int _flagsIndex = 1 << 0; + void _markFlagsDirty() { + _dirtyFields |= _flagsIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + int get actions => _actions; + int _actions; + + static const int _actionsIndex = 1 << 1; + + /// Whether the [actions] field has been updated but has not been applied to + /// the DOM yet. + bool get isActionsDirty => _isDirty(_actionsIndex); + void _markActionsDirty() { + _dirtyFields |= _actionsIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + int get textSelectionBase => _textSelectionBase; + int _textSelectionBase; + + static const int _textSelectionBaseIndex = 1 << 2; + + /// Whether the [textSelectionBase] field has been updated but has not been + /// applied to the DOM yet. + bool get isTextSelectionBaseDirty => _isDirty(_textSelectionBaseIndex); + void _markTextSelectionBaseDirty() { + _dirtyFields |= _textSelectionBaseIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + int get textSelectionExtent => _textSelectionExtent; + int _textSelectionExtent; + + static const int _textSelectionExtentIndex = 1 << 3; + + /// Whether the [textSelectionExtent] field has been updated but has not been + /// applied to the DOM yet. + bool get isTextSelectionExtentDirty => _isDirty(_textSelectionExtentIndex); + void _markTextSelectionExtentDirty() { + _dirtyFields |= _textSelectionExtentIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + int get scrollChildren => _scrollChildren; + int _scrollChildren; + + static const int _scrollChildrenIndex = 1 << 4; + + /// Whether the [scrollChildren] field has been updated but has not been + /// applied to the DOM yet. + bool get isScrollChildrenDirty => _isDirty(_scrollChildrenIndex); + void _markScrollChildrenDirty() { + _dirtyFields |= _scrollChildrenIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + int get scrollIndex => _scrollIndex; + int _scrollIndex; + + static const int _scrollIndexIndex = 1 << 5; + + /// Whether the [scrollIndex] field has been updated but has not been + /// applied to the DOM yet. + bool get isScrollIndexDirty => _isDirty(_scrollIndexIndex); + void _markScrollIndexDirty() { + _dirtyFields |= _scrollIndexIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + double get scrollPosition => _scrollPosition; + double _scrollPosition; + + static const int _scrollPositionIndex = 1 << 6; + + /// Whether the [scrollPosition] field has been updated but has not been + /// applied to the DOM yet. + bool get isScrollPositionDirty => _isDirty(_scrollPositionIndex); + void _markScrollPositionDirty() { + _dirtyFields |= _scrollPositionIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + double get scrollExtentMax => _scrollExtentMax; + double _scrollExtentMax; + + static const int _scrollExtentMaxIndex = 1 << 7; + + /// Whether the [scrollExtentMax] field has been updated but has not been + /// applied to the DOM yet. + bool get isScrollExtentMaxDirty => _isDirty(_scrollExtentMaxIndex); + void _markScrollExtentMaxDirty() { + _dirtyFields |= _scrollExtentMaxIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + double get scrollExtentMin => _scrollExtentMin; + double _scrollExtentMin; + + static const int _scrollExtentMinIndex = 1 << 8; + + /// Whether the [scrollExtentMin] field has been updated but has not been + /// applied to the DOM yet. + bool get isScrollExtentMinDirty => _isDirty(_scrollExtentMinIndex); + void _markScrollExtentMinDirty() { + _dirtyFields |= _scrollExtentMinIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + ui.Rect get rect => _rect; + ui.Rect _rect; + + static const int _rectIndex = 1 << 9; + + /// Whether the [rect] field has been updated but has not been + /// applied to the DOM yet. + bool get isRectDirty => _isDirty(_rectIndex); + void _markRectDirty() { + _dirtyFields |= _rectIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + String get label => _label; + String _label; + + /// Whether this object contains a non-empty label. + bool get hasLabel => _label != null && _label.isNotEmpty; + + static const int _labelIndex = 1 << 10; + + /// Whether the [label] field has been updated but has not been + /// applied to the DOM yet. + bool get isLabelDirty => _isDirty(_labelIndex); + void _markLabelDirty() { + _dirtyFields |= _labelIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + String get hint => _hint; + String _hint; + + static const int _hintIndex = 1 << 11; + + /// Whether the [hint] field has been updated but has not been + /// applied to the DOM yet. + bool get isHintDirty => _isDirty(_hintIndex); + void _markHintDirty() { + _dirtyFields |= _hintIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + String get value => _value; + String _value; + + /// Whether this object contains a non-empty value. + bool get hasValue => _value != null && _value.isNotEmpty; + + static const int _valueIndex = 1 << 12; + + /// Whether the [value] field has been updated but has not been + /// applied to the DOM yet. + bool get isValueDirty => _isDirty(_valueIndex); + void _markValueDirty() { + _dirtyFields |= _valueIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + String get increasedValue => _increasedValue; + String _increasedValue; + + static const int _increasedValueIndex = 1 << 13; + + /// Whether the [increasedValue] field has been updated but has not been + /// applied to the DOM yet. + bool get isIncreasedValueDirty => _isDirty(_increasedValueIndex); + void _markIncreasedValueDirty() { + _dirtyFields |= _increasedValueIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + String get decreasedValue => _decreasedValue; + String _decreasedValue; + + static const int _decreasedValueIndex = 1 << 14; + + /// Whether the [decreasedValue] field has been updated but has not been + /// applied to the DOM yet. + bool get isDecreasedValueDirty => _isDirty(_decreasedValueIndex); + void _markDecreasedValueDirty() { + _dirtyFields |= _decreasedValueIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + ui.TextDirection get textDirection => _textDirection; + ui.TextDirection _textDirection; + + static const int _textDirectionIndex = 1 << 15; + + /// Whether the [textDirection] field has been updated but has not been + /// applied to the DOM yet. + bool get isTextDirectionDirty => _isDirty(_textDirectionIndex); + void _markTextDirectionDirty() { + _dirtyFields |= _textDirectionIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + Float64List get transform => _transform; + Float64List _transform; + + static const int _transformIndex = 1 << 16; + + /// Whether the [transform] field has been updated but has not been + /// applied to the DOM yet. + bool get isTransformDirty => _isDirty(_transformIndex); + void _markTransformDirty() { + _dirtyFields |= _transformIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + Int32List get childrenInTraversalOrder => _childrenInTraversalOrder; + Int32List _childrenInTraversalOrder; + + static const int _childrenInTraversalOrderIndex = 1 << 19; + + /// Whether the [childrenInTraversalOrder] field has been updated but has not + /// been applied to the DOM yet. + bool get isChildrenInTraversalOrderDirty => + _isDirty(_childrenInTraversalOrderIndex); + void _markChildrenInTraversalOrderDirty() { + _dirtyFields |= _childrenInTraversalOrderIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + Int32List get childrenInHitTestOrder => _childrenInHitTestOrder; + Int32List _childrenInHitTestOrder; + + static const int _childrenInHitTestOrderIndex = 1 << 20; + + /// Whether the [childrenInHitTestOrder] field has been updated but has not + /// been applied to the DOM yet. + bool get isChildrenInHitTestOrderDirty => + _isDirty(_childrenInHitTestOrderIndex); + void _markChildrenInHitTestOrderDirty() { + _dirtyFields |= _childrenInHitTestOrderIndex; + } + + /// See [ui.SemanticsUpdateBuilder.updateNode]. + Int32List get additionalActions => _additionalActions; + Int32List _additionalActions; + + static const int _additionalActionsIndex = 1 << 21; + + /// Whether the [additionalActions] field has been updated but has not been + /// applied to the DOM yet. + bool get isAdditionalActionsDirty => _isDirty(_additionalActionsIndex); + void _markAdditionalActionsDirty() { + _dirtyFields |= _additionalActionsIndex; + } + + /// A unique permanent identifier of the semantics node in the tree. + final int id; + + /// Controls the semantics tree that this node participates in. + final EngineSemanticsOwner owner; + + /// The DOM element used to convey semantics information to the browser. + final html.Element element = html.Element.tag('flt-semantics'); + + /// Bitfield showing which fields have been updated but have not yet been + /// applied to the DOM. + /// + /// Instead of use this field directly, prefer using one of the "is*Dirty" + /// getters, e.g. [isFlagsDirty]. + /// + /// The bitfield supports up to 31 bits. + int _dirtyFields = -1; // initial value is when all relevant bits are set + + /// Whether the field corresponding to the [fieldIndex] has been updated. + bool _isDirty(int fieldIndex) => (_dirtyFields & fieldIndex) != 0; + + /// Returns the HTML element that contains the HTML elements of direct + /// children of this object. + /// + /// The element is created lazily. When the child list is empty this element + /// is not created. This is necessary for "aria-label" to function correctly. + /// The browser will ignore the [label] of HTML element that contain child + /// elements. + html.Element getOrCreateChildContainer() { + if (_childContainerElement == null) { + _childContainerElement = html.Element.tag('flt-semantics-container'); + _childContainerElement.style.position = 'absolute'; + element.append(_childContainerElement); + } + return _childContainerElement; + } + + /// The element that contains the elements belonging to the child semantics + /// nodes. + /// + /// This element is used to correct for [_rect] offsets. It is only non-`null` + /// when there are non-zero children (i.e. when [hasChildren] is `true`). + html.Element _childContainerElement; + + /// The parent of this semantics object. + SemanticsObject _parent; + + /// Whether this node currently has a given [SemanticsFlag]. + bool hasFlag(ui.SemanticsFlag flag) => _flags & flag.index != 0; + + /// Whether [actions] contains the given action. + bool hasAction(ui.SemanticsAction action) => (_actions & action.index) != 0; + + /// Whether this object represents a vertically scrollable area. + bool get isVerticalScrollContainer => + hasAction(ui.SemanticsAction.scrollDown) || + hasAction(ui.SemanticsAction.scrollUp); + + /// Whether this object represents a hotizontally scrollable area. + bool get isHorizontalScrollContainer => + hasAction(ui.SemanticsAction.scrollLeft) || + hasAction(ui.SemanticsAction.scrollRight); + + /// Whether this object has a non-empty list of children. + bool get hasChildren => + _childrenInTraversalOrder != null && _childrenInTraversalOrder.isNotEmpty; + + /// Whether this object represents an editable text field. + bool get isTextField => hasFlag(ui.SemanticsFlag.isTextField); + + /// Updates this object from data received from a semantics [update]. + /// + /// This method creates [SemanticsObject]s for the direct children of this + /// object. However, it does not recursively populate them. + void updateWith(SemanticsNodeUpdate update) { + // Update all field values and their corresponding dirty flags before + // applying the updates to the DOM. + assert(update.flags != null); + if (_flags != update.flags) { + _flags = update.flags; + _markFlagsDirty(); + } + + if (_value != update.value) { + _value = update.value; + _markValueDirty(); + } + + if (_label != update.label) { + _label = update.label; + _markLabelDirty(); + } + + if (_rect != update.rect) { + _rect = update.rect; + _markRectDirty(); + } + + if (_transform != update.transform) { + _transform = update.transform; + _markTransformDirty(); + } + + if (_scrollPosition != update.scrollPosition) { + _scrollPosition = update.scrollPosition; + _markScrollPositionDirty(); + } + + if (_actions != update.actions) { + _actions = update.actions; + _markActionsDirty(); + } + + if (_textSelectionBase != update.textSelectionBase) { + _textSelectionBase = update.textSelectionBase; + _markTextSelectionBaseDirty(); + } + + if (_textSelectionExtent != update.textSelectionExtent) { + _textSelectionExtent = update.textSelectionExtent; + _markTextSelectionExtentDirty(); + } + + if (_scrollChildren != update.scrollChildren) { + _scrollChildren = update.scrollChildren; + _markScrollChildrenDirty(); + } + + if (_scrollIndex != update.scrollIndex) { + _scrollIndex = update.scrollIndex; + _markScrollIndexDirty(); + } + + if (_scrollExtentMax != update.scrollExtentMax) { + _scrollExtentMax = update.scrollExtentMax; + _markScrollExtentMaxDirty(); + } + + if (_scrollExtentMin != update.scrollExtentMin) { + _scrollExtentMin = update.scrollExtentMin; + _markScrollExtentMinDirty(); + } + + if (_hint != update.hint) { + _hint = update.hint; + _markHintDirty(); + } + + if (_increasedValue != update.increasedValue) { + _increasedValue = update.increasedValue; + _markIncreasedValueDirty(); + } + + if (_decreasedValue != update.decreasedValue) { + _decreasedValue = update.decreasedValue; + _markDecreasedValueDirty(); + } + + if (_textDirection != update.textDirection) { + _textDirection = update.textDirection; + _markTextDirectionDirty(); + } + + if (_childrenInHitTestOrder != update.childrenInHitTestOrder) { + _childrenInHitTestOrder = update.childrenInHitTestOrder; + _markChildrenInHitTestOrderDirty(); + } + + if (_childrenInTraversalOrder != update.childrenInTraversalOrder) { + _childrenInTraversalOrder = update.childrenInTraversalOrder; + _markChildrenInTraversalOrderDirty(); + } + + if (_additionalActions != update.additionalActions) { + _additionalActions = update.additionalActions; + _markAdditionalActionsDirty(); + } + + // Apply updates to the DOM. + _updateRoles(); + _updateChildrenInTraversalOrder(); + + // All properties that affect positioning and sizing are checked together + // any one of them triggers position and size recomputation. + if (isRectDirty || isTransformDirty || isScrollPositionDirty) { + recomputePositionAndSize(); + } + + // Make sure we create a child container only when there are children. + assert(_childContainerElement == null || hasChildren); + _dirtyFields = 0; + } + + /// Populates the HTML "role" attribute based on a [condition]. + /// + /// If [condition] is true, sets the value to [ariaRoleName]. + /// + /// If [condition] is false, removes the HTML "role" attribute from [element] + /// if the current role is set to [ariaRoleName]. Otherwise, leaves the value + /// unchanged. This is done so we gracefully handle multiple competing roles. + /// For example, if the role changes from "button" to "img" and tappable role + /// manager attempts to clean up after the image role manager applied the new + /// role, we do not want it to erase the new role. + void setAriaRole(String ariaRoleName, bool condition) { + if (condition) { + element.setAttribute('role', ariaRoleName); + } else if (element.getAttribute('role') == ariaRoleName) { + element.attributes.remove('role'); + } + } + + /// Role managers. + /// + /// [LinkedHashMap] is used to guarantee a stable order for easier debugging + /// and testing. + final LinkedHashMap _roleManagers = + LinkedHashMap(); + + /// Detects the roles that this semantics object corresponds to and manages + /// the lifecycles of [SemanticsObjectRole] objects. + void _updateRoles() { + _updateRole(Role.labelAndValue, hasLabel || hasValue); + _updateRole(Role.textField, isTextField); + _updateRole( + Role.tappable, + hasAction(ui.SemanticsAction.tap) || + hasFlag(ui.SemanticsFlag.isButton)); + _updateRole(Role.incrementable, isIncrementable); + _updateRole(Role.scrollable, + isVerticalScrollContainer || isHorizontalScrollContainer); + _updateRole(Role.checkable, hasFlag(ui.SemanticsFlag.hasCheckedState)); + } + + void _updateRole(Role role, bool enabled) { + RoleManager manager = _roleManagers[role]; + if (enabled) { + if (manager == null) { + manager = _roleFactories[role](this); + _roleManagers[role] = manager; + } + manager.update(); + } else if (manager != null) { + manager.dispose(); + _roleManagers.remove(role); + } + // Nothing to do in the "else case" as it means that we want to disable a + // role that we don't currently have in the first place. + } + + /// Whether the object represents an UI element with "increase" or "decrease" + /// controls, e.g. a slider. + /// + /// Such objects are expressed in HTML using ``. + bool get isIncrementable => + hasAction(ui.SemanticsAction.increase) || + hasAction(ui.SemanticsAction.decrease); + + /// Role-specific adjustment of the vertical position of the child container. + /// + /// This is used, for example, by the [Scrollable] to compensate for the + /// `scrollTop` offset in the DOM. + /// + /// This field must not be null. + double verticalContainerAdjustment = 0.0; + + /// Role-specific adjustment of the horizontal position of the child + /// container. + /// + /// This is used, for example, by the [Scrollable] to compensate for the + /// `scrollLeft` offset in the DOM. + /// + /// This field must not be null. + double horizontalContainerAdjustment = 0.0; + + /// Computes the size and position of [element] and, if this element + /// [hasChildren], of [getOrCreateChildContainer]. + void recomputePositionAndSize() { + element.style + ..width = '${_rect.width}px' + ..height = '${_rect.height}px'; + + final html.Element containerElement = + hasChildren ? getOrCreateChildContainer() : null; + + bool hasZeroRectOffset = _rect.top == 0.0 && _rect.left == 0.0; + bool hasIdentityTransform = + _transform == null || isIdentityFloat64ListTransform(_transform); + + if (hasZeroRectOffset && + hasIdentityTransform && + verticalContainerAdjustment == 0.0 && + horizontalContainerAdjustment == 0.0) { + element.style + ..removeProperty('transform-origin') + ..removeProperty('transform'); + if (containerElement != null) { + containerElement.style + ..removeProperty('transform-origin') + ..removeProperty('transform'); + } + return; + } + + Matrix4 effectiveTransform; + bool effectiveTransformIsIdentity = true; + if (!hasZeroRectOffset) { + if (_transform == null) { + final double left = _rect.left; + final double top = _rect.top; + effectiveTransform = Matrix4.translationValues(left, top, 0.0); + effectiveTransformIsIdentity = (left == 0.0 && top == 0.0); + } else { + // Clone to avoid mutating _transform. + effectiveTransform = Matrix4.fromFloat64List(_transform).clone() + ..translate(_rect.left, _rect.top, 0.0); + effectiveTransformIsIdentity = effectiveTransform.isIdentity(); + } + } else if (!hasIdentityTransform) { + effectiveTransform = Matrix4.fromFloat64List(_transform); + effectiveTransformIsIdentity = false; + } + + if (!effectiveTransformIsIdentity) { + element.style + ..transformOrigin = '0 0 0' + ..transform = matrix4ToCssTransform(effectiveTransform); + } else { + element.style + ..removeProperty('transform-origin') + ..removeProperty('transform'); + } + + if (containerElement != null) { + if (!hasZeroRectOffset || + verticalContainerAdjustment != 0.0 || + horizontalContainerAdjustment != 0.0) { + final double translateX = -_rect.left + horizontalContainerAdjustment; + final double translateY = -_rect.top + verticalContainerAdjustment; + containerElement.style + ..transformOrigin = '0 0 0' + ..transform = 'translate(${translateX}px, ${translateY}px)'; + } else { + containerElement.style + ..removeProperty('transform-origin') + ..removeProperty('transform'); + } + } + } + + Int32List _previousChildrenInTraversalOrder; + + /// Updates the traversal child list of [object] from the given [update]. + /// + /// This method does not recursively update child elements' properties or + /// their grandchildren. This is handled by [updateSemantics] method walking + /// all the update nodes. + void _updateChildrenInTraversalOrder() { + // Remove all children case. + if (_childrenInTraversalOrder == null || + _childrenInTraversalOrder.isEmpty) { + if (_previousChildrenInTraversalOrder == null || + _previousChildrenInTraversalOrder.isEmpty) { + // We must not have created a container element when child list is empty. + assert(_childContainerElement == null); + _previousChildrenInTraversalOrder = _childrenInTraversalOrder; + return; + } + + // We must have created a container element when child list is not empty. + assert(_childContainerElement != null); + + // Remove all children from this semantics object. + for (int childId in _previousChildrenInTraversalOrder) { + owner._detachObject(childId); + } + _previousChildrenInTraversalOrder = null; + _childContainerElement.remove(); + _childContainerElement = null; + _previousChildrenInTraversalOrder = _childrenInTraversalOrder; + return; + } + + final html.Element containerElement = getOrCreateChildContainer(); + + // Empty case. + if (_previousChildrenInTraversalOrder == null || + _previousChildrenInTraversalOrder.isEmpty) { + _previousChildrenInTraversalOrder = _childrenInTraversalOrder; + for (int id in _previousChildrenInTraversalOrder) { + final SemanticsObject child = owner.getOrCreateObject(id); + containerElement.append(child.element); + owner._attachObject(parent: this, child: child); + } + _previousChildrenInTraversalOrder = _childrenInTraversalOrder; + return; + } + + // Both non-empty case. + + // Indices into the new child list pointing at children that also exist in + // the old child list. + final List intersectionIndicesNew = []; + + // Indices into the old child list pointing at children that also exist in + // the new child list. + final List intersectionIndicesOld = []; + + int newIndex = 0; + + // The smallest of the two child list lengths. + final int minLength = math.min( + _previousChildrenInTraversalOrder.length, + _childrenInTraversalOrder.length, + ); + + // Scan forward until first discrepancy. + while (newIndex < minLength && + _previousChildrenInTraversalOrder[newIndex] == + _childrenInTraversalOrder[newIndex]) { + intersectionIndicesNew.add(newIndex); + intersectionIndicesOld.add(newIndex); + newIndex += 1; + } + + // If child lists are identical, do nothing. + if (_previousChildrenInTraversalOrder.length == + _childrenInTraversalOrder.length && + newIndex == _childrenInTraversalOrder.length) { + return; + } + + // If child lists are not identical, continue computing the intersection + // between the two lists. + while (newIndex < _childrenInTraversalOrder.length) { + for (int oldIndex = 0; + oldIndex < _previousChildrenInTraversalOrder.length; + oldIndex += 1) { + if (_previousChildrenInTraversalOrder[oldIndex] == + _childrenInTraversalOrder[newIndex]) { + intersectionIndicesNew.add(newIndex); + intersectionIndicesOld.add(oldIndex); + break; + } + } + newIndex += 1; + } + + // The longest sub-sequence in the old list maximizes the number of children + // that do not need to be moved. + final List longestSequence = + longestIncreasingSubsequence(intersectionIndicesOld); + final List stationaryIds = []; + for (int i = 0; i < longestSequence.length; i += 1) { + stationaryIds.add(_previousChildrenInTraversalOrder[ + intersectionIndicesOld[longestSequence[i]]]); + } + + // Remove children that are no longer in the list. + for (int i = 0; i < _previousChildrenInTraversalOrder.length; i++) { + if (!intersectionIndicesOld.contains(i)) { + // Child not in the intersection. Must be removed. + final childId = _previousChildrenInTraversalOrder[i]; + owner._detachObject(childId); + } + } + + html.Element refNode; + for (int i = _childrenInTraversalOrder.length - 1; i >= 0; i -= 1) { + final int childId = _childrenInTraversalOrder[i]; + final SemanticsObject child = owner.getOrCreateObject(childId); + if (!stationaryIds.contains(childId)) { + if (refNode == null) { + containerElement.append(child.element); + } else { + containerElement.insertBefore(child.element, refNode); + } + owner._attachObject(parent: this, child: child); + } else { + assert(child._parent == this); + } + refNode = child.element; + } + + _previousChildrenInTraversalOrder = _childrenInTraversalOrder; + } + + @override + String toString() { + if (assertionsEnabled) { + final String children = _childrenInTraversalOrder != null && + _childrenInTraversalOrder.isNotEmpty + ? '[${_childrenInTraversalOrder.join(', ')}]' + : ''; + return '$runtimeType(#${id}, children: ${children})'; + } else { + return super.toString(); + } + } +} + +/// Controls how pointer events and browser-detected gestures are treated by +/// the Web Engine. +enum AccessibilityMode { + /// We are not told whether the assistive technology is enabled or not. + /// + /// This is the default mode. + /// + /// In this mode we use a gesture recognition system that deduplicates + /// gestures detected by Flutter with gestures detected by the browser. + unknown, + + /// We are told whether the assistive technology is enabled. + known, +} + +/// Called when the current [GestureMode] changes. +typedef GestureModeCallback = void Function(GestureMode mode); + +/// The method used to detect user gestures. +enum GestureMode { + /// Send pointer events to Flutter to detect gestures using framework-level + /// gesture recognizers and gesture arenas. + pointerEvents, + + /// Listen to browser-detected gestures and report them to the framework as + /// [ui.SemanticsAction]. + browserGestures, +} + +/// The top-level service that manages everything semantics-related. +class EngineSemanticsOwner { + EngineSemanticsOwner._() { + registerHotRestartListener(() { + _rootSemanticsElement?.remove(); + }); + } + + /// The singleton instance that manages semantics. + static EngineSemanticsOwner get instance { + return _instance ??= EngineSemanticsOwner._(); + } + + static EngineSemanticsOwner _instance; + + /// Disables semantics and uninitializes the singleton [instance]. + /// + /// Instances of [EngineSemanticsOwner] are no longer valid after calling this + /// method. Using them will lead to undefined behavior. This method is only + /// meant to be used for testing. + static void debugResetSemantics() { + if (_instance == null) { + return; + } + _instance.semanticsEnabled = false; + _instance = null; + } + + final Map _semanticsTree = {}; + + /// Map [SemanticsObject.id] to parent [SemanticsObject] it was attached to + /// this frame. + Map _attachments = {}; + + /// Declares that the [child] must be attached to the [parent]. + /// + /// Attachments take precendence over detachments (see [_detachObject]). This + /// allows the same node to be detached from one parent in the tree and + /// reattached to another parent. + void _attachObject({SemanticsObject parent, SemanticsObject child}) { + assert(child != null); + assert(parent != null); + child._parent = parent; + _attachments[child.id] = parent; + } + + /// List of objects that were detached this frame. + /// + /// The objects in this list will be detached permanently unless they are + /// reattached via the [_attachObject] method. + List _detachments = []; + + /// Declares that the [SemanticsObject] with the given [id] was detached from + /// its current parent object. + /// + /// The object will be detached permanently unless it is reattached via the + /// [_attachObject] method. + void _detachObject(int id) { + assert(_semanticsTree.containsKey(id)); + final SemanticsObject object = _semanticsTree[id]; + _detachments.add(object); + } + + /// Callbacks called after all objects in the tree have their properties + /// populated and their sizes and locations computed. + /// + /// This list is reset to empty after all callbacks are called. + List _oneTimePostUpdateCallbacks = []; + + /// Schedules a one-time callback to be called after all objects in the tree + /// have their properties populated and their sizes and locations computed. + void addOneTimePostUpdateCallback(ui.VoidCallback callback) { + _oneTimePostUpdateCallbacks.add(callback); + } + + /// Reconciles [_attachments] and [_detachments], and after that calls all + /// the one-time callbacks scheduled via the [addOneTimePostUpdateCallback] + /// method. + void _finalizeTree() { + for (SemanticsObject object in _detachments) { + final SemanticsObject parent = _attachments[object.id]; + if (parent == null) { + // Was not reparented and is removed permanently from the tree. + _semanticsTree.remove(object.id); + object._parent = null; + object.element.remove(); + } else { + assert(object._parent == parent); + assert(object.element.parent == parent._childContainerElement); + } + } + _detachments = []; + _attachments = {}; + + if (_oneTimePostUpdateCallbacks.isNotEmpty) { + for (ui.VoidCallback callback in _oneTimePostUpdateCallbacks) { + callback(); + } + _oneTimePostUpdateCallbacks = []; + } + } + + /// Returns the entire semantics tree for testing. + /// + /// Works only in debug mode. + Map get debugSemanticsTree { + Map result; + assert(() { + result = _semanticsTree; + return true; + }()); + return result; + } + + /// The top-level DOM element of the semantics DOM element tree. + html.Element _rootSemanticsElement; + + TimestampFunction _now = () => DateTime.now(); + + void debugOverrideTimestampFunction(TimestampFunction value) { + _now = value; + } + + void debugResetTimestampFunction() { + _now = () => DateTime.now(); + } + + /// A temporary placeholder used to capture a request to activate semantics. + html.Element _semanticsPlaceholder; + + /// We do not immediately enable semantics when the user requests it, but + /// instead wait for a short period of time before doing it. This is because + /// the request comes as a tap on the [_semanticsPlaceholder]. The tap, + /// depending on the browser, comes as a burst of events. For example, Safari + /// sends "touchstart", "touchend", and "click". So during a short time period + /// we consume all events and prevent forwarding to the framework. Otherwise, + /// the events will be interpreted twice, once as a request to activate + /// semantics, and a second time by Flutter's gesture recognizers. + Timer _semanticsActivationTimer; + + /// The number of events we processed that could potentially activate + /// semantics. + int _semanticsActivationAttempts = 0; + + /// The maximum [_semanticsActivationAttempts] before we give up waiting for + /// the user to enable semantics. + /// + /// This number is arbitrary and can be adjusted if it doesn't work well. + static const int _kMaxSemanticsActivationAttempts = 20; + + /// Whether we are waiting for the user to enable semantics. + bool get _isWaitingToEnableSemantics => _semanticsPlaceholder != null; + + /// Instructs [_tryEnableSemantics] to remove [_semanticsPlaceholder]. + /// + /// On Chrome the placeholder is removed upon any next event. + /// + /// On Safari the placeholder is removed upon the next "touchend" event. This + /// is to prevent Safari from swallowing the event that happens on an element + /// that's being removed. Chrome doesn't have this issue. + bool _schedulePlaceholderRemoval = false; + + /// Attempts to activate semantics. + /// + /// Returns true if the `event` is not related to semantics activation and + /// should be forwarded to the framework. + bool _tryEnableSemantics(html.Event event) { + if (_schedulePlaceholderRemoval) { + final bool removeNow = + browserEngine != BrowserEngine.webkit || event.type == 'touchend'; + if (removeNow) { + _semanticsPlaceholder.remove(); + _semanticsPlaceholder = null; + _semanticsActivationTimer = null; + } + return true; + } + + if (semanticsEnabled) { + // Semantics already enabled, forward to framework as normal. + return true; + } + + _semanticsActivationAttempts += 1; + if (_semanticsActivationAttempts >= _kMaxSemanticsActivationAttempts) { + // We have received multiple user events, none of which resulted in + // semantics activation. This is a signal that the user is not interested + // in semantics, and so we will stop waiting for it. + _schedulePlaceholderRemoval = true; + return true; + } + + const List kInterestingEventTypes = [ + 'click', + 'touchstart', + 'touchend', + ]; + + if (!kInterestingEventTypes.contains(event.type)) { + // The event is not relevant, forward to framework as normal. + return true; + } + + if (_semanticsActivationTimer != null) { + // We are in a waiting period to activate a timer. While the timer is + // active we should consume events pertaining to semantics activation. + // Otherwise the event will also be interpreted by the framework and + // potentially result in activating a gesture in the app. + return false; + } + + // In Chrome the debouncing works well enough to detect accessibility + // request. + final bool blinkEnableConditionPassed = + (browserEngine == BrowserEngine.blink && + _gestureMode == GestureMode.browserGestures); + + // In Safari debouncing doesn't work. Instead we look at where exactly + // (within 1 pixel) the event landed. If it landed exactly in the middle of + // the placeholder we interpret it as a signal to enable accessibility. This + // is because when VoiceOver generates a tap it lands it in the middle of + // the focused element. This method is a bit flawed in that a user's finger + // could theoretically land in the middle of the element too. However, the + // chance of that happening is very small. Even low-end phones typically + // have >2 million pixels (e.g. Moto G4). It is very unlikely that a user + // will land their finger exactly in the middle. In the worst case an + // unlucky user would accidentally enable accessibility and the app will be + // slightly slower than normal, but the app will continue functioning as + // normal. Our semantics tree is designed to not interfere with Flutter's + // gesture detection. + bool safariEnableConditionPassed = false; + if (browserEngine == BrowserEngine.webkit) { + html.Point activationPoint; + + switch (event.type) { + case 'click': + final html.MouseEvent click = event; + activationPoint = click.offset; + break; + case 'touchstart': + case 'touchend': + final html.TouchEvent touch = event; + activationPoint = touch.changedTouches.first.client; + break; + default: + // The event is not relevant, forward to framework as normal. + return true; + } + + assert(activationPoint != null); + + final html.Rectangle activatingElementRect = + domRenderer.glassPaneElement.getBoundingClientRect(); + final double midX = activatingElementRect.left + + (activatingElementRect.right - activatingElementRect.left) / 2; + final double midY = activatingElementRect.top + + (activatingElementRect.bottom - activatingElementRect.top) / 2; + final double deltaX = activationPoint.x - midX; + final double deltaY = activationPoint.y - midY; + final double deltaSquared = deltaX * deltaX + deltaY * deltaY; + if (deltaSquared < 1.0) { + safariEnableConditionPassed = true; + } + } + + if (blinkEnableConditionPassed || safariEnableConditionPassed) { + assert(_semanticsActivationTimer == null); + _semanticsActivationTimer = Timer(const Duration(milliseconds: 300), () { + semanticsEnabled = true; + _schedulePlaceholderRemoval = true; + }); + return false; + } + + // This was not a semantics activating event; forward as normal. + return true; + } + + /// The message in the label for the placeholder element used to enable + /// accessibility. + /// + /// This uses US English as the default message. Set this value prior to + /// calling `runApp` to translate to another language. + static String placeholderMessage = 'Enable accessibility'; + + /// Enables accessibility when the user taps on the glasspane via an + /// accessibility focus. + /// + /// This creates a placeholder inside the glasspane, which, when focused, + /// announces that accessibility can be enabled by tapping. + void autoEnableOnTap(DomRenderer domRenderer) { + _semanticsPlaceholder = html.Element.tag('flt-semantics-placeholder'); + + // Only listen to "click" because other kinds of events are reported via + // PointerBinding. + _semanticsPlaceholder.addEventListener('click', (html.Event event) { + _tryEnableSemantics(event); + }, true); + + _semanticsPlaceholder + ..setAttribute('role', 'button') + ..setAttribute('aria-label', placeholderMessage); + _semanticsPlaceholder.style + ..position = 'absolute' + ..left = '0' + ..top = '0' + ..right = '0' + ..bottom = '0'; + domRenderer.glassPaneElement.append(_semanticsPlaceholder); + } + + /// Whether the user has requested that [updateSemantics] be called when + /// the semantic contents of window changes. + /// + /// The [ui.Window.onSemanticsEnabledChanged] callback is called whenever this + /// value changes. + /// + /// This is separate from accessibility [mode], which controls how gestures + /// are interpreted when this value is true. + bool get semanticsEnabled => _semanticsEnabled; + bool _semanticsEnabled = false; + set semanticsEnabled(bool value) { + if (value == _semanticsEnabled) { + return; + } + _semanticsEnabled = value; + + if (!_semanticsEnabled) { + // We do not process browser events at all when semantics is explicitly + // disabled. All gestures are handled by the framework-level gesture + // recognizers from pointer events. + if (_gestureMode != GestureMode.pointerEvents) { + _gestureMode = GestureMode.pointerEvents; + _notifyGestureModeListeners(); + } + for (int id in _semanticsTree.keys.toList()) { + _detachObject(id); + } + _finalizeTree(); + _rootSemanticsElement?.remove(); + _rootSemanticsElement = null; + _gestureModeClock?.datetime = null; + } + + if (ui.window.onSemanticsEnabledChanged != null) { + ui.window.onSemanticsEnabledChanged(); + } + } + + /// Controls how pointer events and browser-detected gestures are treated by + /// the Web Engine. + /// + /// The default mode is [AccessibilityMode.unknown]. + AccessibilityMode get mode => _mode; + set mode(AccessibilityMode value) { + assert(value != null); + _mode = value; + } + + AccessibilityMode _mode = AccessibilityMode.unknown; + + /// Currently used [GestureMode]. + /// + /// This value changes automatically depending on the incoming input events. + /// Functionality that implements different strategies depending on this mode + /// would use [addGestureModeListener] and [removeGestureModeListener] to get + /// notifications about when the value of this field changes. + GestureMode get gestureMode => _gestureMode; + GestureMode _gestureMode = GestureMode.browserGestures; + + AlarmClock _gestureModeClock; + + AlarmClock _getGestureModeClock() { + if (_gestureModeClock == null) { + _gestureModeClock = AlarmClock(_now); + _gestureModeClock.callback = () { + if (_gestureMode == GestureMode.browserGestures) { + return; + } + + _gestureMode = GestureMode.browserGestures; + _notifyGestureModeListeners(); + }; + } + return _gestureModeClock; + } + + /// Disables browser gestures temporarily because we have detected pointer + /// events. + /// + /// This is used to deduplicate gestures detected by Flutter and gestures + /// detected by the browser. Flutter-detected gestures have higher precedence. + void _temporarilyDisableBrowserGestureMode() { + const _kDebounceThreshold = Duration(milliseconds: 500); + _getGestureModeClock().datetime = _now().add(_kDebounceThreshold); + if (_gestureMode != GestureMode.pointerEvents) { + _gestureMode = GestureMode.pointerEvents; + _notifyGestureModeListeners(); + } + } + + /// Receives DOM events from the pointer event system to correlate with the + /// semantics events; returns true if the event should be forwarded to the + /// framework. + /// + /// The browser sends us both raw pointer events and gestures from + /// [SemanticsObject.element]s. There could be three possibilities: + /// + /// 1. Assistive technology is enabled and we know that it is. + /// 2. Assistive technology is disabled and we know that it isn't. + /// 3. We do not know whether an assistive technology is enabled. + /// + /// If [autoEnableOnTap] was called, this will automatically enable semantics + /// if the user requests it. + /// + /// In the first case we can ignore raw pointer events and only interpret + /// high-level gestures, e.g. "click". + /// + /// In the second case we can ignore high-level gestures and interpret the raw + /// pointer events directly. + /// + /// Finally, in a mode when we do not know if an assistive technology is + /// enabled or not we do a best-effort estimate which to respond to, raw + /// pointer or high-level gestures. We avoid doing both because that will + /// result in double-firing of event listeners, such as `onTap` on a button. + /// An approach we use is to measure the distance between the last pointer + /// event and a gesture event. If a gesture is receive "soon" after the last + /// received pointer event (determined by a heuristic), it is debounced as it + /// is likely that the gesture detected from the pointer even will do the + /// right thing. However, if we receive a standalone gesture we will map it + /// onto a [ui.SemanticsAction] to be processed by the framework. + bool receiveGlobalEvent(html.Event event) { + // For pointer event reference see: + // + // https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events + const _pointerEventTypes = [ + 'pointerdown', + 'pointermove', + 'pointerup', + 'pointercancel', + 'touchstart', + 'touchend', + 'touchmove', + 'touchcancel', + 'mousedown', + 'mousemove', + 'mouseup', + ]; + + if (_pointerEventTypes.contains(event.type)) { + _temporarilyDisableBrowserGestureMode(); + } + + if (!_isWaitingToEnableSemantics) { + // Forward to framework as normal. + return true; + } else { + return _tryEnableSemantics(event); + } + } + + /// Callbacks called when the [GestureMode] changes. + /// + /// Callbacks are called synchronously. HTML DOM updates made in a callback + /// take effect in the current animation frame and/or the current message loop + /// event. + List _gestureModeListeners = []; + + /// Calls the [callback] every time the current [GestureMode] changes. + /// + /// The callback is called synchronously. HTML DOM updates made in the + /// callback take effect in the current animation frame and/or the current + /// message loop event. + void addGestureModeListener(GestureModeCallback callback) { + _gestureModeListeners.add(callback); + } + + /// Stops calling the [callback] when the [GestureMode] changes. + /// + /// The passed [callback] must be the exact same object as the one passed to + /// [addGestureModeListener]. + void removeGestureModeListener(GestureModeCallback callback) { + assert(_gestureModeListeners.contains(callback)); + _gestureModeListeners.remove(callback); + } + + void _notifyGestureModeListeners() { + for (int i = 0; i < _gestureModeListeners.length; i++) { + _gestureModeListeners[i](_gestureMode); + } + } + + /// Whether a gesture event of type [eventType] should be accepted as a + /// semantic action. + /// + /// If [mode] is [AccessibilityMode.known] the gesture is always accepted if + /// [semanticsEnabled] is `true`, and it is always rejected if + /// [semanticsEnabled] is `false`. + /// + /// If [mode] is [AccessibilityMode.unknown] the gesture is accepted if it is + /// not accompanied by pointer events. In the presence of pointer events we + /// delegate to Flutter's gesture detection system to produce gestures. + bool shouldAcceptBrowserGesture(String eventType) { + if (_mode == AccessibilityMode.known) { + // Do not ignore accessibility gestures in known mode, unless semantics + // is explicitly disabled. + return semanticsEnabled; + } + + const List pointerDebouncedGestures = [ + 'click', + 'scroll', + ]; + + if (pointerDebouncedGestures.contains(eventType)) { + return _gestureMode == GestureMode.browserGestures; + } + + return false; + } + + /// Looks up a [SemanticsObject] in the semantics tree by ID, or creates a new + /// instance if it does not exist. + SemanticsObject getOrCreateObject(int id) { + SemanticsObject object = _semanticsTree[id]; + if (object == null) { + object = SemanticsObject(id, this); + _semanticsTree[id] = object; + } + return object; + } + + /// Updates the semantics tree from data in the [uiUpdate]. + void updateSemantics(ui.SemanticsUpdate uiUpdate) { + if (!_semanticsEnabled) { + return; + } + + SemanticsUpdate update = uiUpdate; + for (SemanticsNodeUpdate nodeUpdate in update._nodeUpdates) { + SemanticsObject object = getOrCreateObject(nodeUpdate.id); + object.updateWith(nodeUpdate); + } + + if (_rootSemanticsElement == null) { + final SemanticsObject root = _semanticsTree[0]; + _rootSemanticsElement = root.element; + // We render semantics inside the glasspane for proper focus and event + // handling. If semantics is behind the glasspane, the phone will disable + // focusing by touch, only by tabbing around the UI. If semantics is in + // front of glasspane, then DOM event won't bubble up to the glasspane so + // it can forward events to the framework. + domRenderer.glassPaneElement.append(_rootSemanticsElement); + } + + _finalizeTree(); + + assert(_semanticsTree.containsKey(0)); // must contain root node + assert(() { + // Validate tree + _semanticsTree.forEach((int id, SemanticsObject object) { + assert(id == object.id); + // Ensure child ID list is consistent with the parent-child + // relationship of the semantics tree. + if (object._childrenInTraversalOrder != null) { + for (int childId in object._childrenInTraversalOrder) { + final SemanticsObject child = _semanticsTree[childId]; + if (child == null) { + throw AssertionError('Child #${childId} is missing in the tree.'); + } + if (child._parent == null) { + throw AssertionError( + 'Child #${childId} of parent #${object.id} has null parent ' + 'reference.'); + } + if (!identical(child._parent, object)) { + throw AssertionError( + 'Parent #${object.id} has child #${childId}. However, the ' + 'child is attached to #${child._parent.id}.'); + } + } + } + }); + + // Validate that all updates were applied + for (SemanticsNodeUpdate update in update._nodeUpdates) { + // Node was added to the tree. + assert(_semanticsTree.containsKey(update.id)); + // We created a DOM element for it. + assert(_semanticsTree[update.id].element != null); + } + + return true; + }()); + } +} + +/// Computes the [longest increasing subsequence](http://en.wikipedia.org/wiki/Longest_increasing_subsequence). +/// +/// Returns list of indices (rather than values) into [list]. +/// +/// Complexity: n*log(n) +List longestIncreasingSubsequence(List list) { + final len = list.length; + final predecessors = []; + final mins = [0]; + int longest = 0; + for (int i = 0; i < len; i++) { + // Binary search for the largest positive `j ≤ longest` + // such that `list[mins[j]] < list[i]` + int elem = list[i]; + int lo = 1; + int hi = longest; + while (lo <= hi) { + int mid = (lo + hi) ~/ 2; + if (list[mins[mid]] < elem) { + lo = mid + 1; + } else { + hi = mid - 1; + } + } + // After searching, `lo` is 1 greater than the + // length of the longest prefix of `list[i]` + int expansionIndex = lo; + // The predecessor of `list[i]` is the last index of + // the subsequence of length `newLongest - 1` + predecessors.add(mins[expansionIndex - 1]); + if (expansionIndex >= mins.length) { + mins.add(i); + } else { + mins[expansionIndex] = i; + } + if (expansionIndex > longest) { + // If we found a subsequence longer than any we've + // found yet, update `longest` + longest = expansionIndex; + } + } + // Reconstruct the longest subsequence + final seq = new List(longest); + int k = mins[longest]; + for (int i = longest - 1; i >= 0; i--) { + seq[i] = k; + k = predecessors[k]; + } + return seq; +} diff --git a/lib/stub_ui/lib/src/engine/semantics/tappable.dart b/lib/stub_ui/lib/src/engine/semantics/tappable.dart new file mode 100644 index 0000000000000..751c89fbafdc1 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/semantics/tappable.dart @@ -0,0 +1,60 @@ +// 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. + +part of engine; + +/// Listens to HTML "click" gestures detected by the browser. +/// +/// This gestures is different from the click and tap gestures detected by the +/// framework from raw pointer events. When an assistive technology is enabled +/// the browser may not send us pointer events. In that mode we forward HTML +/// click as [ui.SemanticsAction.tap]. +class Tappable extends RoleManager { + Tappable(SemanticsObject semanticsObject) + : super(Role.tappable, semanticsObject); + + html.EventListener _clickListener; + + @override + void update() { + final html.Element element = semanticsObject.element; + + semanticsObject.setAriaRole( + 'button', semanticsObject.hasFlag(ui.SemanticsFlag.isButton)); + + // Excluding text fields because text fields have browser-specific logic + // for recognizing taps and activating the keyboard. + if (semanticsObject.hasAction(ui.SemanticsAction.tap) && + !semanticsObject.hasFlag(ui.SemanticsFlag.isTextField)) { + if (_clickListener == null) { + _clickListener = (_) { + if (semanticsObject.owner.gestureMode != + GestureMode.browserGestures) { + return; + } + ui.window.onSemanticsAction( + semanticsObject.id, ui.SemanticsAction.tap, null); + }; + element.addEventListener('click', _clickListener); + } + } else { + _stopListening(); + } + } + + void _stopListening() { + if (_clickListener == null) { + return; + } + + semanticsObject.element.removeEventListener('click', _clickListener); + _clickListener = null; + } + + @override + void dispose() { + _stopListening(); + semanticsObject.setAriaRole('button', false); + } +} diff --git a/lib/stub_ui/lib/src/engine/semantics/text_field.dart b/lib/stub_ui/lib/src/engine/semantics/text_field.dart new file mode 100644 index 0000000000000..4d234f7774963 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/semantics/text_field.dart @@ -0,0 +1,145 @@ +// 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. + +part of engine; + +/// Manages semantics objects that represent editable text fields. +/// +/// This role is implemented via a content-editable HTML element. This role does +/// not proactively switch modes depending on the current +/// [EngineSemanticsOwner.gestureMode]. However, in Chrome on Android it ignores +/// browser gestures when in pointer mode. In Safari on iOS touch events are +/// used to detect text box invocation. This is because Safari issues touch +/// events even when Voiceover is enabled. +class TextField extends RoleManager { + TextField(SemanticsObject semanticsObject) + : super(Role.textField, semanticsObject) { + final html.HtmlElement editableDomElement = + semanticsObject.hasFlag(ui.SemanticsFlag.isMultiline) + ? html.TextAreaElement() + : html.InputElement(); + persistentTextEditingElement = PersistentTextEditingElement( + editableDomElement, + onDomElementSwap: _setupDomElement, + ); + _setupDomElement(); + } + + PersistentTextEditingElement persistentTextEditingElement; + html.Element get _textFieldElement => persistentTextEditingElement.domElement; + + void _setupDomElement() { + // On iOS, even though the semantic text field is transparent, the cursor + // and text highlighting are still visible. The cursor and text selection + // are made invisible by CSS in [DomRenderer.reset]. + // But there's one more case where iOS highlights text. That's when there's + // and autocorrect suggestion. To disable that, we have to do the following: + _textFieldElement + ..spellcheck = false + ..setAttribute('spellcheck', 'false') + ..setAttribute('autocorrect', 'off') + ..setAttribute('autocomplete', 'off') + ..setAttribute('data-semantics-role', 'text-field'); + + _textFieldElement.style + ..position = 'absolute' + // `top` and `left` are intentionally set to zero here. + // + // The text field would live inside a `` which should + // already be positioned using semantics.rect. + // + // See also: + // + // * [SemanticsObject.recomputePositionAndSize], which sets the position + // and size of the parent `` element. + ..top = '0' + ..left = '0' + ..width = '${semanticsObject.rect.width}px' + ..height = '${semanticsObject.rect.height}px'; + semanticsObject.element.append(_textFieldElement); + + switch (browserEngine) { + case BrowserEngine.blink: + case BrowserEngine.unknown: + _initializeForBlink(); + break; + case BrowserEngine.webkit: + _initializeForWebkit(); + break; + } + } + + /// Chrome on Android reports text field activation as a "click" event. + /// + /// When in browser gesture mode, the focus is forwarded to the framework as + /// a tap to initialize editing. + void _initializeForBlink() { + _textFieldElement.addEventListener('focus', (html.Event event) { + if (semanticsObject.owner.gestureMode != GestureMode.browserGestures) { + return; + } + + textEditing.useCustomEditableElement(persistentTextEditingElement); + ui.window + .onSemanticsAction(semanticsObject.id, ui.SemanticsAction.tap, null); + }); + } + + /// Safari on iOS reports text field activation via touch events. + /// + /// This emulates a tap recognizer to detect the activation. Because touch + /// events are present regardless of whether accessibility is enabled or not, + /// this mode is always enabled. + void _initializeForWebkit() { + num lastTouchStartOffsetX; + num lastTouchStartOffsetY; + + _textFieldElement.addEventListener('touchstart', (html.Event event) { + textEditing.useCustomEditableElement(persistentTextEditingElement); + html.TouchEvent touchEvent = event; + lastTouchStartOffsetX = touchEvent.changedTouches.last.client.x; + lastTouchStartOffsetY = touchEvent.changedTouches.last.client.y; + }, true); + + _textFieldElement.addEventListener('touchend', (html.Event event) { + html.TouchEvent touchEvent = event; + + if (lastTouchStartOffsetX != null) { + assert(lastTouchStartOffsetY != null); + final num offsetX = touchEvent.changedTouches.last.client.x; + final num offsetY = touchEvent.changedTouches.last.client.y; + + // This should match the similar constant define in: + // + // lib/src/gestures/constants.dart + // + // The value is pre-squared so we have to do less math at runtime. + const double kTouchSlop = 18.0 * 18.0; // Logical pixels squared + + if (offsetX * offsetX + offsetY * offsetY < kTouchSlop) { + // Recognize it as a tap that requires a keyboard. + ui.window.onSemanticsAction( + semanticsObject.id, ui.SemanticsAction.tap, null); + } + } else { + assert(lastTouchStartOffsetY == null); + } + + lastTouchStartOffsetX = null; + lastTouchStartOffsetY = null; + }, true); + } + + @override + void update() { + // The user is editing the semantic text field directly, so there's no need + // to do any update here. + } + + @override + void dispose() { + _textFieldElement.remove(); + textEditing.stopUsingCustomEditableElement(); + } +} diff --git a/lib/stub_ui/lib/src/engine/services/message_codec.dart b/lib/stub_ui/lib/src/engine/services/message_codec.dart new file mode 100644 index 0000000000000..076658911df5c --- /dev/null +++ b/lib/stub_ui/lib/src/engine/services/message_codec.dart @@ -0,0 +1,137 @@ +// 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. + +part of engine; + +/// A message encoding/decoding mechanism. +/// +/// Both operations throw an exception, if conversion fails. Such situations +/// should be treated as programming errors. +/// +/// See also: +/// +/// * [BasicMessageChannel], which use [MessageCodec]s for communication +/// between Flutter and platform plugins. +abstract class MessageCodec { + /// Encodes the specified [message] in binary. + /// + /// Returns null if the message is null. + ByteData encodeMessage(T message); + + /// Decodes the specified [message] from binary. + /// + /// Returns null if the message is null. + T decodeMessage(ByteData message); +} + +/// An command object representing the invocation of a named method. +@immutable +class MethodCall { + /// Creates a [MethodCall] representing the invocation of [method] with the + /// specified [arguments]. + const MethodCall(this.method, [this.arguments]) : assert(method != null); + + /// The name of the method to be called. + final String method; + + /// The arguments for the method. + /// + /// Must be a valid value for the [MethodCodec] used. + final dynamic arguments; + + @override + String toString() => '$runtimeType($method, $arguments)'; +} + +/// A codec for method calls and enveloped results. +/// +/// All operations throw an exception, if conversion fails. +/// +/// See also: +/// +/// * [MethodChannel], which use [MethodCodec]s for communication +/// between Flutter and platform plugins. +/// * [EventChannel], which use [MethodCodec]s for communication +/// between Flutter and platform plugins. +abstract class MethodCodec { + /// Encodes the specified [methodCall] into binary. + ByteData encodeMethodCall(MethodCall methodCall); + + /// Decodes the specified [methodCall] from binary. + MethodCall decodeMethodCall(ByteData methodCall); + + /// Decodes the specified result [envelope] from binary. + /// + /// Throws [PlatformException], if [envelope] represents an error, otherwise + /// returns the enveloped result. + dynamic decodeEnvelope(ByteData envelope); + + /// Encodes a successful [result] into a binary envelope. + ByteData encodeSuccessEnvelope(dynamic result); + + /// Encodes an error result into a binary envelope. + /// + /// The specified error [code], human-readable error [message], and error + /// [details] correspond to the fields of [PlatformException]. + ByteData encodeErrorEnvelope( + {@required String code, String message, dynamic details}); +} + +/// Thrown to indicate that a platform interaction failed in the platform +/// plugin. +/// +/// See also: +/// +/// * [MethodCodec], which throws a [PlatformException], if a received result +/// envelope represents an error. +/// * [MethodChannel.invokeMethod], which completes the returned future +/// with a [PlatformException], if invoking the platform plugin method +/// results in an error envelope. +/// * [EventChannel.receiveBroadcastStream], which emits +/// [PlatformException]s as error events, whenever an event received from the +/// platform plugin is wrapped in an error envelope. +class PlatformException implements Exception { + /// Creates a [PlatformException] with the specified error [code] and optional + /// [message], and with the optional error [details] which must be a valid + /// value for the [MethodCodec] involved in the interaction. + PlatformException({ + @required this.code, + this.message, + this.details, + }) : assert(code != null); + + /// An error code. + final String code; + + /// A human-readable error message, possibly null. + final String message; + + /// Error details, possibly null. + final dynamic details; + + @override + String toString() => 'PlatformException($code, $message, $details)'; +} + +/// Thrown to indicate that a platform interaction failed to find a handling +/// plugin. +/// +/// See also: +/// +/// * [MethodChannel.invokeMethod], which completes the returned future +/// with a [MissingPluginException], if no plugin handler for the method call +/// was found. +/// * [OptionalMethodChannel.invokeMethod], which completes the returned future +/// with null, if no plugin handler for the method call was found. +class MissingPluginException implements Exception { + /// Creates a [MissingPluginException] with an optional human-readable + /// error message. + MissingPluginException([this.message]); + + /// A human-readable error message, possibly null. + final String message; + + @override + String toString() => 'MissingPluginException($message)'; +} diff --git a/lib/stub_ui/lib/src/engine/services/message_codecs.dart b/lib/stub_ui/lib/src/engine/services/message_codecs.dart new file mode 100644 index 0000000000000..710fe4830cfc2 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/services/message_codecs.dart @@ -0,0 +1,154 @@ +// 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. + +part of engine; + +/// [MessageCodec] with unencoded binary messages represented using [ByteData]. +/// +/// On Android, messages will be represented using `java.nio.ByteBuffer`. +/// On iOS, messages will be represented using `NSData`. +class BinaryCodec implements MessageCodec { + /// Creates a [MessageCodec] with unencoded binary messages represented using + /// [ByteData]. + const BinaryCodec(); + + @override + ByteData decodeMessage(ByteData message) => message; + + @override + ByteData encodeMessage(ByteData message) => message; +} + +/// [MessageCodec] with UTF-8 encoded String messages. +/// +/// On Android, messages will be represented using `java.util.String`. +/// On iOS, messages will be represented using `NSString`. +class StringCodec implements MessageCodec { + /// Creates a [MessageCodec] with UTF-8 encoded String messages. + const StringCodec(); + + @override + String decodeMessage(ByteData message) { + if (message == null) return null; + return utf8.decoder.convert(message.buffer.asUint8List()); + } + + @override + ByteData encodeMessage(String message) { + if (message == null) return null; + final Uint8List encoded = utf8.encoder.convert(message); + return encoded.buffer.asByteData(); + } +} + +/// [MessageCodec] with UTF-8 encoded JSON messages. +/// +/// Supported messages are acyclic values of these forms: +/// +/// * null +/// * [bool]s +/// * [num]s +/// * [String]s +/// * [List]s of supported values +/// * [Map]s from strings to supported values +/// +/// On Android, messages are decoded using the `org.json` library. +/// On iOS, messages are decoded using the `NSJSONSerialization` library. +/// In both cases, the use of top-level simple messages (null, [bool], [num], +/// and [String]) is supported (by the Flutter SDK). The decoded value will be +/// null/nil for null, and identical to what would result from decoding a +/// singleton JSON array with a Boolean, number, or string value, and then +/// extracting its single element. +class JSONMessageCodec implements MessageCodec { + // The codec serializes messages as defined by the JSON codec of the + // dart:convert package. The format used must match the Android and + // iOS counterparts. + + /// Creates a [MessageCodec] with UTF-8 encoded JSON messages. + const JSONMessageCodec(); + + @override + ByteData encodeMessage(dynamic message) { + if (message == null) return null; + return const StringCodec().encodeMessage(json.encode(message)); + } + + @override + dynamic decodeMessage(ByteData message) { + if (message == null) return message; + return json.decode(const StringCodec().decodeMessage(message)); + } +} + +/// [MethodCodec] with UTF-8 encoded JSON method calls and result envelopes. +/// +/// Values supported as method arguments and result payloads are those supported +/// by [JSONMessageCodec]. +class JSONMethodCodec implements MethodCodec { + // The codec serializes method calls, and result envelopes as outlined below. + // This format must match the Android and iOS counterparts. + // + // * Individual values are serialized as defined by the JSON codec of the + // dart:convert package. + // * Method calls are serialized as two-element maps, with the method name + // keyed by 'method' and the arguments keyed by 'args'. + // * Reply envelopes are serialized as either: + // * one-element lists containing the successful result as its single + // element, or + // * three-element lists containing, in order, an error code String, an + // error message String, and an error details value. + + /// Creates a [MethodCodec] with UTF-8 encoded JSON method calls and result + /// envelopes. + const JSONMethodCodec(); + + @override + ByteData encodeMethodCall(MethodCall call) { + return const JSONMessageCodec().encodeMessage({ + 'method': call.method, + 'args': call.arguments, + }); + } + + @override + MethodCall decodeMethodCall(ByteData methodCall) { + final dynamic decoded = const JSONMessageCodec().decodeMessage(methodCall); + if (decoded is! Map) + throw new FormatException('Expected method call Map, got $decoded'); + final dynamic method = decoded['method']; + final dynamic arguments = decoded['args']; + if (method is String) return new MethodCall(method, arguments); + throw new FormatException('Invalid method call: $decoded'); + } + + @override + dynamic decodeEnvelope(ByteData envelope) { + final dynamic decoded = const JSONMessageCodec().decodeMessage(envelope); + if (decoded is! List) + throw new FormatException('Expected envelope List, got $decoded'); + if (decoded.length == 1) return decoded[0]; + if (decoded.length == 3 && + decoded[0] is String && + (decoded[1] == null || decoded[1] is String)) + throw new PlatformException( + code: decoded[0], + message: decoded[1], + details: decoded[2], + ); + throw new FormatException('Invalid envelope: $decoded'); + } + + @override + ByteData encodeSuccessEnvelope(dynamic result) { + return const JSONMessageCodec().encodeMessage([result]); + } + + @override + ByteData encodeErrorEnvelope( + {@required String code, String message, dynamic details}) { + assert(code != null); + return const JSONMessageCodec() + .encodeMessage([code, message, details]); + } +} diff --git a/lib/stub_ui/lib/src/engine/shadow.dart b/lib/stub_ui/lib/src/engine/shadow.dart new file mode 100644 index 0000000000000..9a74c27039f56 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/shadow.dart @@ -0,0 +1,369 @@ +// 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. + +part of engine; + +/// This code is ported from the AngularDart SCSS. +/// +/// See: https://github.com/dart-lang/angular_components/blob/master/lib/css/material/_shadow.scss +class ElevationShadow { + /// Applies a standard transition style for box-shadow to box-shadow. + static void applyShadowTransition(html.CssStyleDeclaration style) { + style.transition = 'box-shadow .28s cubic-bezier(.4, 0, .2, 1)'; + } + + /// Disables box-shadow. + static void applyShadowNone(html.CssStyleDeclaration style) { + style.boxShadow = 'none'; + } + + /// Applies a standard shadow to the selected element(s). + /// + /// This rule is great for things that need a static shadow. If the elevation + /// of the shadow needs to be changed dynamically, use [applyShadow]. + /// + /// Valid values: 2, 3, 4, 6, 8, 12, 16, 24 + static void applyShadowElevation(html.CssStyleDeclaration style, + {@required int dp, @required ui.Color color}) { + const keyUmbraOpacity = 0.2; + const keyPenumbraOpacity = 0.14; + const ambientShadowOpacity = 0.12; + + final String rgb = '${color.red}, ${color.green}, ${color.blue}'; + if (dp == 2) { + style.boxShadow = '0 2px 2px 0 rgba($rgb, $keyPenumbraOpacity), ' + '0 3px 1px -2px rgba($rgb, $ambientShadowOpacity), ' + '0 1px 5px 0 rgba($rgb, $keyUmbraOpacity)'; + } else if (dp == 3) { + style.boxShadow = '0 3px 4px 0 rgba($rgb, $keyPenumbraOpacity), ' + '0 3px 3px -2px rgba($rgb, $ambientShadowOpacity), ' + '0 1px 8px 0 rgba($rgb, $keyUmbraOpacity)'; + } else if (dp == 4) { + style.boxShadow = '0 4px 5px 0 rgba($rgb, $keyPenumbraOpacity), ' + '0 1px 10px 0 rgba($rgb, $ambientShadowOpacity), ' + '0 2px 4px -1px rgba($rgb, $keyUmbraOpacity)'; + } else if (dp == 6) { + style.boxShadow = '0 6px 10px 0 rgba($rgb, $keyPenumbraOpacity), ' + '0 1px 18px 0 rgba($rgb, $ambientShadowOpacity), ' + '0 3px 5px -1px rgba($rgb, $keyUmbraOpacity)'; + } else if (dp == 8) { + style.boxShadow = '0 8px 10px 1px rgba($rgb, $keyPenumbraOpacity), ' + '0 3px 14px 2px rgba($rgb, $ambientShadowOpacity), ' + '0 5px 5px -3px rgba($rgb, $keyUmbraOpacity)'; + } else if (dp == 12) { + style.boxShadow = '0 12px 17px 2px rgba($rgb, $keyPenumbraOpacity), ' + '0 5px 22px 4px rgba($rgb, $ambientShadowOpacity), ' + '0 7px 8px -4px rgba($rgb, $keyUmbraOpacity)'; + } else if (dp == 16) { + style.boxShadow = '0 16px 24px 2px rgba($rgb, $keyPenumbraOpacity), ' + '0 6px 30px 5px rgba($rgb, $ambientShadowOpacity), ' + '0 8px 10px -5px rgba($rgb, $keyUmbraOpacity)'; + } else { + style.boxShadow = '0 24px 38px 3px rgba($rgb, $keyPenumbraOpacity), ' + '0 9px 46px 8px rgba($rgb, $ambientShadowOpacity), ' + '0 11px 15px -7px rgba($rgb, $keyUmbraOpacity)'; + } + } + + /// Applies the shadow styles to the selected element. + /// + /// Use the attributes below to control the shadow. + /// + /// - `animated` -- Whether to animate the shadow transition. + /// - `elevation` -- Z-elevation of shadow. Valid Values: 1,2,3,4,5 + static void applyShadow( + html.CssStyleDeclaration style, double elevation, ui.Color color) { + applyShadowTransition(style); + + if (elevation <= 0.0) { + applyShadowNone(style); + } else if (elevation <= 1.0) { + applyShadowElevation(style, dp: 2, color: color); + } else if (elevation <= 2.0) { + applyShadowElevation(style, dp: 4, color: color); + } else if (elevation <= 3.0) { + applyShadowElevation(style, dp: 6, color: color); + } else if (elevation <= 4.0) { + applyShadowElevation(style, dp: 8, color: color); + } else if (elevation <= 5.0) { + applyShadowElevation(style, dp: 16, color: color); + } else { + applyShadowElevation(style, dp: 24, color: color); + } + } + + static List computeCanvasShadows( + double elevation, ui.Color color) { + if (elevation <= 0.0) { + return const []; + } else if (elevation <= 1.0) { + return computeShadowElevation(dp: 2, color: color); + } else if (elevation <= 2.0) { + return computeShadowElevation(dp: 4, color: color); + } else if (elevation <= 3.0) { + return computeShadowElevation(dp: 6, color: color); + } else if (elevation <= 4.0) { + return computeShadowElevation(dp: 8, color: color); + } else if (elevation <= 5.0) { + return computeShadowElevation(dp: 16, color: color); + } else { + return computeShadowElevation(dp: 24, color: color); + } + } + + /// Expands rect to include size of shadow. + /// + /// Computed from shadow elevation offset + spread, blur + static ui.Rect computeShadowRect(ui.Rect r, double elevation) { + // We are computing this rect by computing the maximum "reach" of the shadow + // by summing the computed shadow offset and the blur for the given + // elevation. We are assuming that a blur of '1' corresponds to 1 pixel, + // although the web spec says that this is not necessarily the case. + // However, it seems to be a good conservative estimate. + if (elevation <= 0.0) { + return r; + } else if (elevation <= 1.0) { + return ui.Rect.fromLTRB( + r.left - 2.5, r.top - 1.5, r.right + 3, r.bottom + 4); + } else if (elevation <= 2.0) { + return ui.Rect.fromLTRB(r.left - 5, r.top - 3, r.right + 6, r.bottom + 7); + } else if (elevation <= 3.0) { + return ui.Rect.fromLTRB( + r.left - 9, r.top - 8, r.right + 9, r.bottom + 11); + } else if (elevation <= 4.0) { + return ui.Rect.fromLTRB( + r.left - 10, r.top - 6, r.right + 10, r.bottom + 14); + } else if (elevation <= 5.0) { + return ui.Rect.fromLTRB( + r.left - 15, r.top - 9, r.right + 20, r.bottom + 30); + } else { + return ui.Rect.fromLTRB( + r.left - 23, r.top - 14, r.right + 23, r.bottom + 45); + } + } + + static List computeShadowElevation( + {@required int dp, @required ui.Color color}) { + final int red = color.red; + final int green = color.green; + final int blue = color.blue; + + final penumbraColor = ui.Color.fromARGB(36, red, green, blue); + final ambientShadowColor = ui.Color.fromARGB(31, red, green, blue); + final umbraColor = ui.Color.fromARGB(51, red, green, blue); + + final List result = []; + if (dp == 2) { + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 2.0, + blur: 1.0, + spread: 0.0, + color: penumbraColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 3.0, + blur: 0.5, + spread: -2.0, + color: ambientShadowColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 1.0, + blur: 2.5, + spread: 0.0, + color: umbraColor, + )); + } else if (dp == 3) { + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 1.5, + blur: 4.0, + spread: 0.0, + color: penumbraColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 3.0, + blur: 1.5, + spread: -2.0, + color: ambientShadowColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 1.0, + blur: 4.0, + spread: 0.0, + color: umbraColor, + )); + } else if (dp == 4) { + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 4.0, + blur: 2.5, + spread: 0.0, + color: penumbraColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 1.0, + blur: 5.0, + spread: 0.0, + color: ambientShadowColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 2.0, + blur: 2.0, + spread: -1.0, + color: umbraColor, + )); + } else if (dp == 6) { + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 6.0, + blur: 5.0, + spread: 0.0, + color: penumbraColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 1.0, + blur: 9.0, + spread: 0.0, + color: ambientShadowColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 3.0, + blur: 2.5, + spread: -1.0, + color: umbraColor, + )); + } else if (dp == 8) { + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 4.0, + blur: 10.0, + spread: 1.0, + color: penumbraColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 3.0, + blur: 7.0, + spread: 2.0, + color: ambientShadowColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 5.0, + blur: 2.5, + spread: -3.0, + color: umbraColor, + )); + } else if (dp == 12) { + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 12.0, + blur: 8.5, + spread: 2.0, + color: penumbraColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 5.0, + blur: 11.0, + spread: 4.0, + color: ambientShadowColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 7.0, + blur: 4.0, + spread: -4.0, + color: umbraColor, + )); + } else if (dp == 16) { + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 16.0, + blur: 12.0, + spread: 2.0, + color: penumbraColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 6.0, + blur: 15.0, + spread: 5.0, + color: ambientShadowColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 0.0, + blur: 5.0, + spread: -5.0, + color: umbraColor, + )); + } else { + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 24.0, + blur: 18.0, + spread: 3.0, + color: penumbraColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 9.0, + blur: 23.0, + spread: 8.0, + color: ambientShadowColor, + )); + + result.add(CanvasShadow( + offsetX: 0.0, + offsetY: 11.0, + blur: 7.5, + spread: -7.0, + color: umbraColor, + )); + } + return result; + } +} + +class CanvasShadow { + CanvasShadow({ + @required this.offsetX, + @required this.offsetY, + @required this.blur, + @required this.spread, + @required this.color, + }); + + final double offsetX; + final double offsetY; + final double blur; + // TODO(yjbanov): is there a way to implement/emulate spread on Canvas2D? + final double spread; + final ui.Color color; +} diff --git a/lib/stub_ui/lib/src/engine/text/font_collection.dart b/lib/stub_ui/lib/src/engine/text/font_collection.dart new file mode 100644 index 0000000000000..de83342b4e1c3 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/text/font_collection.dart @@ -0,0 +1,230 @@ +// 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. + +part of engine; + +const _testFontFamily = 'Ahem'; +const _testFontUrl = 'packages/flutter_web/assets/Ahem.ttf'; +const _robotoFontUrl = 'packages/flutter_web_ui/assets/Roboto-Regular.ttf'; + +/// This class is responsible for registering and loading fonts. +/// +/// Once an asset manager has been set in the framework, call +/// [registerFonts] with it to register fonts declared in the +/// font manifest. If test fonts are enabled, then call +/// [registerTestFonts] as well. +class FontCollection { + _FontManager _assetFontManager; + _FontManager _testFontManager; + + /// Reads the font manifest using the [assetManager] and registers all of the + /// fonts declared within. + Future registerFonts(AssetManager assetManager) async { + ByteData byteData; + + try { + byteData = await assetManager.load('FontManifest.json'); + } on AssetManagerException catch (e) { + if (e.httpStatus == 404) { + html.window.console + .warn('Font manifest does not exist at `${e.url}` – ignoring.'); + return; + } else { + rethrow; + } + } + + if (byteData == null) { + throw new AssertionError( + 'There was a problem trying to load FontManifest.json'); + } + + final List fontManifest = + json.decode(utf8.decode(byteData.buffer.asUint8List())); + if (fontManifest == null) { + throw new AssertionError( + 'There was a problem trying to load FontManifest.json'); + } + + if (supportsFontLoadingApi) { + _assetFontManager = _FontManager(); + } else { + _assetFontManager = _PolyfillFontManager(); + } + + // If not on Chrome, add Roboto to the bundled fonts since it is provided + // by default by Flutter. + if (browserEngine != BrowserEngine.blink) { + _assetFontManager + .registerAsset('Roboto', 'url($_robotoFontUrl)', {}); + } + + for (Map fontFamily in fontManifest) { + final String family = fontFamily['family']; + final List fontAssets = fontFamily['fonts']; + + for (Map fontAsset in fontAssets) { + final String asset = fontAsset['asset']; + final descriptors = {}; + for (var descriptor in fontAsset.keys) { + if (descriptor != 'asset') { + descriptors[descriptor] = '${fontAsset[descriptor]}'; + } + } + _assetFontManager.registerAsset( + family, 'url(${assetManager.getAssetUrl(asset)})', descriptors); + } + } + } + + /// Registers fonts that are used by tests. + void debugRegisterTestFonts() { + _testFontManager = _FontManager(); + _testFontManager.registerAsset( + _testFontFamily, 'url($_testFontUrl)', const {}); + } + + /// Returns a [Future] that completes when the registered fonts are loaded + /// and ready to be used. + Future ensureFontsLoaded() async { + await _assetFontManager?.ensureFontsLoaded(); + await _testFontManager?.ensureFontsLoaded(); + } + + /// Unregister all fonts that have been registered. + void clear() { + _assetFontManager = null; + _testFontManager = null; + if (supportsFontLoadingApi) { + html.document.fonts.clear(); + } + } +} + +/// Manages a collection of fonts and ensures they are loaded. +class _FontManager { + final _fontLoadingFutures = >[]; + + factory _FontManager() { + if (supportsFontLoadingApi) { + return _FontManager._(); + } else { + return _PolyfillFontManager(); + } + } + + _FontManager._(); + + void registerAsset( + String family, + String asset, + Map descriptors, + ) { + final fontFace = html.FontFace(family, asset, descriptors); + _fontLoadingFutures.add(fontFace + .load() + .then((_) => html.document.fonts.add(fontFace), onError: (e) { + html.window.console + .warn('Error while trying to load font family "$family":\n$e'); + return null; + })); + } + + /// Returns a [Future] that completes when all fonts that have been + /// registered with this font manager have been loaded and are ready to use. + Future ensureFontsLoaded() { + return Future.wait(_fontLoadingFutures); + } +} + +/// A font manager that works without using the CSS Font Loading API. +/// +/// The CSS Font Loading API is not implemented in IE 11 or Edge. To tell if a +/// font is loaded, we continuously measure some text using that font until the +/// width changes. +class _PolyfillFontManager extends _FontManager { + _PolyfillFontManager() : super._(); + + /// A String containing characters whose width varies greatly between fonts. + static const _testString = 'giItT1WQy@!-/#'; + + static const Duration _fontLoadTimeout = const Duration(seconds: 2); + static const Duration _fontLoadRetryDuration = + const Duration(milliseconds: 50); + + @override + void registerAsset( + String family, + String asset, + Map descriptors, + ) { + final paragraph = html.ParagraphElement(); + paragraph.style.position = 'absolute'; + paragraph.style.visibility = 'hidden'; + paragraph.style.fontSize = '72px'; + paragraph.style.fontFamily = 'sans-serif'; + if (descriptors['style'] != null) { + paragraph.style.fontStyle = descriptors['style']; + } + if (descriptors['weight'] != null) { + paragraph.style.fontWeight = descriptors['weight']; + } + paragraph.text = _testString; + + html.document.body.append(paragraph); + final sansSerifWidth = paragraph.offsetWidth; + + paragraph.style.fontFamily = '$family, sans-serif'; + + Completer completer = Completer(); + + DateTime _fontLoadStart; + + void _watchWidth() { + if (paragraph.offsetWidth != sansSerifWidth) { + paragraph.remove(); + completer.complete(); + } else { + if (DateTime.now().difference(_fontLoadStart) > _fontLoadTimeout) { + completer.completeError( + Exception('Timed out trying to load font: $family')); + } else { + Timer(_fontLoadRetryDuration, _watchWidth); + } + } + } + + final fontStyleMap = {}; + fontStyleMap['font-family'] = "'$family'"; + fontStyleMap['src'] = asset; + if (descriptors['style'] != null) { + fontStyleMap['font-style'] = descriptors['style']; + } + if (descriptors['weight'] != null) { + fontStyleMap['font-weight'] = descriptors['weight']; + } + final fontFaceDeclaration = fontStyleMap.keys + .map((name) => '$name: ${fontStyleMap[name]};') + .join(' '); + final fontLoadStyle = html.StyleElement(); + fontLoadStyle.type = 'text/css'; + fontLoadStyle.innerHtml = '@font-face { $fontFaceDeclaration }'; + html.document.head.append(fontLoadStyle); + + // HACK: If this is an icon font, then when it loads it won't change the + // width of our test string. So we just have to hope it loads before the + // layout phase. + if (family.toLowerCase().contains('icon')) { + paragraph.remove(); + return; + } + + _fontLoadStart = DateTime.now(); + _watchWidth(); + + _fontLoadingFutures.add(completer.future); + } +} + +final bool supportsFontLoadingApi = html.document.fonts != null; diff --git a/lib/stub_ui/lib/src/engine/text/measurement.dart b/lib/stub_ui/lib/src/engine/text/measurement.dart new file mode 100644 index 0000000000000..8a6089c7dc5eb --- /dev/null +++ b/lib/stub_ui/lib/src/engine/text/measurement.dart @@ -0,0 +1,324 @@ +// 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. + +part of engine; + +/// Measures paragraphs of text using a shared top-level absolutely positioned +/// element and [ParagraphRuler]s. +class TextMeasurementService { + TextMeasurementService._({@required this.rulerCacheCapacity}) { + _rulerHost.style + ..position = 'fixed' + ..visibility = 'hidden' + ..overflow = 'hidden' + ..top = '0' + ..left = '0' + ..width = '0' + ..height = '0'; + html.document.body.append(_rulerHost); + registerHotRestartListener(() { + _rulerHost?.remove(); + }); + } + + /// Initializes the text measurement service singleton. + static TextMeasurementService initialize({@required int rulerCacheCapacity}) { + _instance = + TextMeasurementService._(rulerCacheCapacity: rulerCacheCapacity); + return _instance; + } + + /// The text measurement service singleton. + static TextMeasurementService get instance => _instance; + static TextMeasurementService _instance; + + final int rulerCacheCapacity; + + final html.CanvasRenderingContext2D canvasContext = + html.CanvasElement().context2D; + + /// Hosts a cache of rulers that measure text. + /// + /// This element exists purely for organizational purposes. Otherwise the + /// rulers would be attached to the `` element polluting the element + /// tree and making it hard to navigate. It does not serve any functional + /// purpose. + final html.Element _rulerHost = html.Element.tag('flt-ruler-host'); + + /// The cache of rulers used to measure text. + /// + /// Each ruler is keyed by paragraph style. This allows us to setup the + /// ruler's DOM structure once during the very first measurement of a given + /// paragraph style. Subsequent measurements could reuse the same ruler and + /// only swap the text contents. This minimizes the amount of work a browser + /// needs to do when measure many pieces of text with the same style. + /// + /// What makes this cache effective is the fact that a typical application + /// only uses a limited number of text styles. Using too many text styles on + /// the same screen is considered bad for user experience. + Map get rulers => _rulers; + Map _rulers = + {}; + + bool _rulerCacheCleanupScheduled = false; + + void _scheduleRulerCacheCleanup() { + if (!_rulerCacheCleanupScheduled) { + _rulerCacheCleanupScheduled = true; + scheduleMicrotask(() { + _rulerCacheCleanupScheduled = false; + cleanUpRulerCache(); + }); + } + } + + /// If ruler cache size exceeds [rulerCacheCapacity], evicts those rulers that + /// were used the least. + /// + /// Resets hit counts back to zero. + void cleanUpRulerCache() { + if (_rulers.length > rulerCacheCapacity) { + List sortedByUsage = _rulers.values.toList(); + sortedByUsage.sort((ParagraphRuler a, ParagraphRuler b) { + return b.hitCount - a.hitCount; + }); + _rulers = {}; + for (int i = 0; i < sortedByUsage.length; i++) { + var ruler = sortedByUsage[i]; + ruler.resetHitCount(); + if (i < rulerCacheCapacity) { + // Retain this ruler. + _rulers[ruler.style] = ruler; + } else { + // This ruler did not have enough usage this frame to be retained. + ruler.dispose(); + } + } + } + } + + /// Adds an element used for measuring text as a child of [_rulerHost]. + void addHostElement(html.DivElement element) { + _rulerHost.append(element); + } + + /// Measures the paragraph and sets the values directly on the [paragraph] + /// object. + void measure(ui.Paragraph paragraph, ui.ParagraphConstraints constraints) { + final ParagraphGeometricStyle style = + paragraph.webOnlyGetParagraphGeometricStyle(); + final ParagraphRuler ruler = _findOrCreateRuler(style); + + if (assertionsEnabled) { + if (paragraph.webOnlyGetPlainText() == null) { + domRenderer.debugRichTextLayout(); + } else { + domRenderer.debugPlainTextLayout(); + } + } + + RulerCacheEntry cacheEntry = ruler.cacheLookup(paragraph, constraints); + if (cacheEntry != null) { + cacheEntry.applyToParagraph(paragraph); + ruler._hitCount++; + return; + } + + ruler.willMeasure(paragraph); + ruler.measureAll(constraints); + + final String plainText = paragraph.webOnlyGetPlainText(); + // When the text has a new line, we should always use multi-line mode. + final bool hasNewline = plainText?.contains('\n') ?? false; + if (!hasNewline && ruler.singleLineDimensions.width <= constraints.width) { + _measureSingleLineParagraph(ruler, paragraph, constraints); + } else { + // Assert: If text doesn't have new line for infinite constraints we + // should have called single line measure paragraph instead. + assert(hasNewline || constraints.width != double.infinity); + _measureMultiLineParagraph(ruler, paragraph, constraints); + } + ruler.didMeasure(); + } + + /// Performs measurements on the given [paragraph] as a single line with no + /// constraints. + /// + /// This method has no side-effects as it doesn't mutate the + /// paragraph, unlike [measure]. + TextDimensions measureSingleLineText(ui.Paragraph paragraph) { + final style = paragraph.webOnlyGetParagraphGeometricStyle(); + final ParagraphRuler ruler = _findOrCreateRuler(style); + + ruler.willMeasure(paragraph); + ruler.measureAsSingleLine(); + final TextDimensions dimensions = ruler.singleLineDimensions; + ruler.didMeasure(); + return dimensions; + } + + /// Measures the width of the given [paragraph] as a single line with no + /// constraints. + /// + /// Since only the width is needed, this method uses the [measureText] Canvas + /// API which is significantly faster than DOM measurement. + double measureSingleLineWidth(String text, ParagraphGeometricStyle style) { + assert( + style.letterSpacing == null && + style.wordSpacing == null && + style.decoration == null, + 'Cannot measure text using canvas if it uses ' + 'letter spacing, word spacing or decoration: $style'); + canvasContext.font = style.cssFontString; + return canvasContext.measureText(text).width; + } + + /// Delegates to a [ParagraphRuler] to measure a list of text boxes that + /// enclose the given range of text. + List measureBoxesForRange( + ui.Paragraph paragraph, + ui.ParagraphConstraints constraints, { + int start, + int end, + double alignOffset, + ui.TextDirection textDirection, + }) { + final ParagraphGeometricStyle style = + paragraph.webOnlyGetParagraphGeometricStyle(); + final ParagraphRuler ruler = _findOrCreateRuler(style); + + return ruler.measureBoxesForRange( + paragraph.webOnlyGetPlainText(), + constraints, + start: start, + end: end, + alignOffset: alignOffset, + textDirection: textDirection, + ); + } + + ParagraphRuler _findOrCreateRuler(ParagraphGeometricStyle style) { + final ParagraphRuler ruler = _rulers[style]; + if (ruler != null) { + if (assertionsEnabled) { + domRenderer.debugRulerCacheHit(); + } + return ruler; + } + + if (assertionsEnabled) { + domRenderer.debugRulerCacheMiss(); + } + _scheduleRulerCacheCleanup(); + return _rulers[style] = ParagraphRuler(style); + } + + // TODO(yjbanov): this is a hack we use to compute ideographic baseline; this + // number is the ratio ideographic/alphabetic for font Ahem, + // which matches the Flutter number. It may be completely wrong + // for any other font. We'll need to eventually fix this. That + // said Flutter doesn't seem to use ideographic baseline for + // anything as of this writing. + static const _baselineRatioHack = 1.1662499904632568; + + /// Called when we have determined that the paragraph fits the [constraints] + /// without wrapping. + /// + /// This means that: + /// * `width == maxIntrinsicWidth` - we gave it more horizontal space than + /// it needs and so the paragraph won't expand beyond `maxIntrinsicWidth`. + /// * `height` is the height computed by `measureAsSingleLine`; giving the + /// paragraph the width constraint won't change its height as we already + /// determined that it fits within the constraint without wrapping. + /// * `alphabeticBaseline` is also final for the same reason as the `height` + /// value. + /// + /// This method still needs to measure `minIntrinsicWidth`. + void _measureSingleLineParagraph(ParagraphRuler ruler, ui.Paragraph paragraph, + ui.ParagraphConstraints constraints) { + final double width = constraints.width; + final double minIntrinsicWidth = ruler.minIntrinsicDimensions.width; + double maxIntrinsicWidth = ruler.singleLineDimensions.width; + final double alphabeticBaseline = ruler.alphabeticBaseline; + final double height = ruler.singleLineDimensions.height; + + maxIntrinsicWidth = + _applySubPixelRoundingHack(minIntrinsicWidth, maxIntrinsicWidth); + final ideographicBaseline = alphabeticBaseline * _baselineRatioHack; + final cacheEntry = RulerCacheEntry(constraints.width, + isSingleLine: true, + width: width, + height: height, + lineHeight: height, + minIntrinsicWidth: minIntrinsicWidth, + maxIntrinsicWidth: maxIntrinsicWidth, + alphabeticBaseline: alphabeticBaseline, + ideographicBaseline: ideographicBaseline); + ruler.cacheMeasurement(paragraph, constraints, cacheEntry); + cacheEntry.applyToParagraph(paragraph); + } + + /// Called when we have determined that the paragraph needs to wrap into + /// multiple lines to fit the [constraints], i.e. its `maxIntrinsicWidth` is + /// bigger than the available horizontal space. + /// + /// While `maxIntrinsicWidth` is still good from the call to + /// `measureAsSingleLine`, we need to re-measure with the width constraint + /// and get new values for width, height and alphabetic baseline. We also need + /// to measure `minIntrinsicWidth`. + void _measureMultiLineParagraph(ParagraphRuler ruler, ui.Paragraph paragraph, + ui.ParagraphConstraints constraints) { + // If constraint is infinite, we must use _measureSingleLineParagraph + final double width = constraints.width; + final double minIntrinsicWidth = ruler.minIntrinsicDimensions.width; + double maxIntrinsicWidth = ruler.singleLineDimensions.width; + final double alphabeticBaseline = ruler.alphabeticBaseline; + final double height = ruler.constrainedDimensions.height; + + double lineHeight = height; + if (paragraph.webOnlyGetParagraphGeometricStyle().maxLines != null) { + lineHeight = ruler.lineHeightDimensions.height; + } + + maxIntrinsicWidth = + _applySubPixelRoundingHack(minIntrinsicWidth, maxIntrinsicWidth); + assert(minIntrinsicWidth <= maxIntrinsicWidth); + final ideographicBaseline = alphabeticBaseline * _baselineRatioHack; + final cacheEntry = RulerCacheEntry(constraints.width, + isSingleLine: false, + width: width, + height: height, + lineHeight: lineHeight, + minIntrinsicWidth: minIntrinsicWidth, + maxIntrinsicWidth: maxIntrinsicWidth, + alphabeticBaseline: alphabeticBaseline, + ideographicBaseline: ideographicBaseline); + ruler.cacheMeasurement(paragraph, constraints, cacheEntry); + cacheEntry.applyToParagraph(paragraph); + } + + /// This hack is needed because `offsetWidth` rounds the value to the nearest + /// whole number. On a very rare occasion the minimum intrinsic width reported + /// by the browser is slightly bigger than the reported maximum intrinsic + /// width. If the discrepancy overlaps 0.5 then the rounding happens in + /// opposite directions. + /// + /// For example, if minIntrinsicWidth == 99.5 and maxIntrinsicWidth == 99.48, + /// then minIntrinsicWidth is rounded up to 100, and maxIntrinsicWidth is + /// rounded down to 99. + // TODO(yjbanov): remove the need for this hack. + static double _applySubPixelRoundingHack( + double minIntrinsicWidth, double maxIntrinsicWidth) { + if (minIntrinsicWidth <= maxIntrinsicWidth) { + return maxIntrinsicWidth; + } + + if (minIntrinsicWidth - maxIntrinsicWidth < 2.0) { + return minIntrinsicWidth; + } + + throw Exception('minIntrinsicWidth ($minIntrinsicWidth) is greater than ' + 'maxIntrinsicWidth ($maxIntrinsicWidth).'); + } +} diff --git a/lib/stub_ui/lib/src/engine/text/ruler.dart b/lib/stub_ui/lib/src/engine/text/ruler.dart new file mode 100644 index 0000000000000..80ea85ebb6318 --- /dev/null +++ b/lib/stub_ui/lib/src/engine/text/ruler.dart @@ -0,0 +1,723 @@ +// 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. + +part of engine; + +/// Contains the subset of [ui.ParagraphStyle] properties that affect layout. +class ParagraphGeometricStyle { + ParagraphGeometricStyle({ + this.fontWeight, + this.fontStyle, + this.fontFamily, + this.fontSize, + this.lineHeight, + this.maxLines, + this.letterSpacing, + this.wordSpacing, + this.decoration, + this.ellipsis, + }); + + final ui.FontWeight fontWeight; + final ui.FontStyle fontStyle; + final String fontFamily; + final double fontSize; + final double lineHeight; + final int maxLines; + final double letterSpacing; + final double wordSpacing; + final String decoration; + final String ellipsis; + + // Since all fields above are primitives, cache hashcode since ruler lookups + // use this style as key. + int _cachedHashCode; + + /// Returns the font-family that should be used to style the paragraph. It may + /// or may not be different from [fontFamily]: + /// + /// - Always returns "Ahem" in tests. + /// - Provides correct defaults when [fontFamily] doesn't have a value. + String get effectiveFontFamily { + if (assertionsEnabled) { + // In widget tests we use a predictable-size font "Ahem". This makes + // widget tests predictable and less flaky. + if (domRenderer.debugIsInWidgetTest) { + return 'Ahem'; + } + } + if (fontFamily == null || fontFamily.isEmpty) { + return DomRenderer.defaultFontFamily; + } + return fontFamily; + } + + String _cssFontString; + + /// Cached font string that can be used in CSS. + /// + /// See . + String get cssFontString { + if (_cssFontString == null) { + _cssFontString = _buildCssFontString(); + } + return _cssFontString; + } + + String _buildCssFontString() { + final result = StringBuffer(); + + // Font style + if (fontStyle != null) { + result.write(fontStyle == ui.FontStyle.normal ? 'normal' : 'italic'); + } else { + result.write(DomRenderer.defaultFontStyle); + } + result.write(' '); + + // Font weight. + if (fontWeight != null) { + result.write(ui.webOnlyFontWeightToCss(fontWeight)); + } else { + result.write(DomRenderer.defaultFontWeight); + } + result.write(' '); + + if (fontSize != null) { + result.write(fontSize.floor()); + result.write('px'); + } else { + result.write(DomRenderer.defaultFontSize); + } + result.write(' '); + result.write(effectiveFontFamily); + + return result.toString(); + } + + @override + bool operator ==(dynamic other) { + if (identical(this, other)) return true; + if (other.runtimeType != runtimeType) return false; + final ParagraphGeometricStyle typedOther = other; + return fontWeight == typedOther.fontWeight && + fontStyle == typedOther.fontStyle && + fontFamily == typedOther.fontFamily && + fontSize == typedOther.fontSize && + lineHeight == typedOther.lineHeight && + maxLines == typedOther.maxLines && + letterSpacing == typedOther.letterSpacing && + wordSpacing == typedOther.wordSpacing && + decoration == typedOther.decoration && + ellipsis == typedOther.ellipsis; + } + + @override + int get hashCode => _cachedHashCode ??= ui.hashValues( + fontWeight, + fontStyle, + fontFamily, + fontSize, + lineHeight, + maxLines, + letterSpacing, + wordSpacing, + decoration, + ellipsis, + ); + + @override + String toString() { + if (assertionsEnabled) { + return '$runtimeType(fontWeight: $fontWeight, fontStyle: $fontStyle,' + ' fontFamily: $fontFamily, fontSize: $fontSize,' + ' lineHeight: $lineHeight,' + ' maxLines: $maxLines,' + ' letterSpacing: $letterSpacing,' + ' wordSpacing: $wordSpacing,' + ' decoration: $decoration,' + ' ellipsis: $ellipsis,' + ')'; + } else { + return super.toString(); + } + } +} + +/// Provides text dimensions found on [_element]. The idea behind this class is +/// to allow the [ParagraphRuler] to mutate multiple dom elements and allow +/// consumers to lazily read the measurements. +/// +/// The [ParagraphRuler] would have multiple instances of [TextDimensions] with +/// different backing elements for different types of measurements. When a +/// measurement is needed, the [ParagraphRuler] would mutate all the backing +/// elements at once. The consumer of the ruler can later read those +/// measurements. +/// +/// The rationale behind this is to minimize browser reflows by batching dom +/// writes first, then performing all the reads. +class TextDimensions { + TextDimensions(this._element); + + final html.HtmlElement _element; + html.Rectangle _cachedBoundingClientRect; + + /// Attempts to efficiently copy text from [from]. + /// + /// The primary efficiency gain is from rare occurrence of rich text in + /// typical apps. + void updateText(ui.Paragraph from, ParagraphGeometricStyle style) { + assert(from != null); + assert(_element != null); + assert(from.webOnlyDebugHasSameRootStyle(style)); + assert(() { + bool wasEmptyOrPlainText = _element.childNodes.isEmpty || + (_element.childNodes.length == 1 && + _element.childNodes.first is html.Text); + if (!wasEmptyOrPlainText) { + throw Exception( + 'Failed to copy text into the paragraph measuring element. The ' + 'element already contains rich text "${_element.innerHtml}". It is ' + 'likely that a previous measurement did not clean up after ' + 'itself.'); + } + return true; + }()); + + _invalidateBoundsCache(); + String plainText = from.webOnlyGetPlainText(); + if (plainText != null) { + // Plain text: just set the string. The paragraph's style is assumed to + // match the style set on the `element`. Setting text as plain string is + // faster because it doesn't change the DOM structure or CSS attributes, + // and therefore doesn't trigger style recalculations in the browser. + _element.text = plainText; + } else { + // Rich text: deeply copy contents. This is the slow case that should be + // avoided if fast layout performance is desired. + final html.Element copy = from.webOnlyGetParagraphElement().clone(true); + _element.children.addAll(copy.children); + } + } + + // Updated element style width. + void updateWidth(String cssWidth) { + _invalidateBoundsCache(); + _element.style.width = cssWidth; + } + + void _invalidateBoundsCache() { + _cachedBoundingClientRect = null; + } + + /// Sets text of contents to a single space character to measure empty text. + void updateTextToSpace() { + _invalidateBoundsCache(); + _element.text = ' '; + } + + /// Applies geometric style properties to the [element]. + void applyStyle(ParagraphGeometricStyle style) { + _element.style + ..fontSize = style.fontSize != null ? '${style.fontSize.floor()}px' : null + ..fontFamily = style.effectiveFontFamily + ..fontWeight = style.fontWeight != null + ? ui.webOnlyFontWeightToCss(style.fontWeight) + : null + ..fontStyle = style.fontStyle != null + ? style.fontStyle == ui.FontStyle.normal ? 'normal' : 'italic' + : null + ..letterSpacing = + style.letterSpacing != null ? '${style.letterSpacing}px' : null + ..wordSpacing = + style.wordSpacing != null ? '${style.wordSpacing}px' : null + ..textDecoration = style.decoration; + if (style.lineHeight != null) { + _element.style.lineHeight = style.lineHeight.toString(); + } + _invalidateBoundsCache(); + } + + /// Appends element and probe to hostElement that is setup for a specific + /// TextStyle. + void appendToHost(html.HtmlElement hostElement) { + hostElement.append(_element); + _invalidateBoundsCache(); + } + + html.Rectangle _readAndCacheMetrics() => + _cachedBoundingClientRect ??= _element.getBoundingClientRect(); + + /// The width of the paragraph being measured. + double get width => _readAndCacheMetrics().width; + + /// The height of the paragraph being measured. + double get height => _readAndCacheMetrics().height; +} + +/// Performs 4 types of measurements: +/// +/// 1. Single line: can be prepared by calling [measureAsSingleLine]. +/// Measurement values will be available at [singleLineDimensions]. +/// +/// 2. Minimum intrinsic width: can be prepared by calling +/// [measureMinIntrinsicWidth]. Measurement values will be available at +/// [minIntrinsicDimensions]. +/// +/// 3. Constrained: can be prepared by calling [measureWithConstraints] and +/// passing the constraints. Measurement values will be available at +/// [constrainedDimensions]. +/// +/// 4. Boxes: within a paragraph, it measures a list of text boxes that enclose +/// a given range of text. +/// +/// For performance reasons, it's advised to use [measureAll] and then reading +/// whatever measurements are needed. This causes the browser to only reflow +/// once instead of many times. +/// +/// The [measureAll] method performs the first 3 stateful measurements but not +/// the 4th one. +/// +/// This class is both reusable and stateful. Use it carefully. The correct +/// usage is as follows: +/// +/// * First, call [willMeasure] passing it the paragraph to be measured. +/// * Call any of the [measureAsSingleLine], [measureMinIntrinsicWidth], +/// [measureWithConstraints], or [measureAll], to prepare the respective +/// measurement. These methods can be called any number of times. +/// * Call [didMeasure] to indicate that you are done with the paragraph passed +/// to the [willMeasure] method. +/// +/// It is safe to reuse this object as long as paragraphs passed to the +/// [measure] method have the same style. +/// +/// The only stateless method provided by this class is [measureBoxesForRange] +/// that doesn't rely on [willMeasure] and [didMeasure] lifecycle methods. +/// +/// This class optimizes for plain text paragraphs, which should constitute the +/// majority of paragraphs in typical apps. +class ParagraphRuler { + /// The only style that this [ParagraphRuler] measures text. + final ParagraphGeometricStyle style; + + /// Probe to use for measuring alphabetic base line. + final _probe = html.DivElement(); + + /// Cached value of alphabetic base line. + double _cachedAlphabeticBaseline; + + ParagraphRuler(this.style) { + _configureSingleLineHostElements(); + // Since alphabeticbaseline will be same regardless of constraints. + // We can measure it using a probe on the single line dimensions + // host. + _singleLineHost.append(_probe); + _configureMinIntrinsicHostElements(); + _configureConstrainedHostElements(); + } + + /// The alphabetic baseline of the paragraph being measured. + double get alphabeticBaseline => + _cachedAlphabeticBaseline ??= _probe.getBoundingClientRect().bottom; + + // Elements used to measure single-line metrics. + final html.DivElement _singleLineHost = html.DivElement(); + final TextDimensions singleLineDimensions = + TextDimensions(html.ParagraphElement()); + + // Elements used to measure minIntrinsicWidth. + final html.DivElement _minIntrinsicHost = html.DivElement(); + TextDimensions minIntrinsicDimensions = + TextDimensions(html.ParagraphElement()); + + // Elements used to measure metrics under a width constraint. + final html.DivElement _constrainedHost = html.DivElement(); + TextDimensions constrainedDimensions = + TextDimensions(html.ParagraphElement()); + + // Elements used to measure the line-height metric. + html.DivElement _lineHeightHost; + TextDimensions _lineHeightDimensions; + TextDimensions get lineHeightDimensions { + // Lazily create the elements for line-height measurement since they are not + // always needed. + if (_lineHeightDimensions == null) { + _lineHeightHost = html.DivElement(); + _lineHeightDimensions = TextDimensions(html.ParagraphElement()); + _configureLineHeightHostElements(); + } + return _lineHeightDimensions; + } + + /// The number of times this ruler was used this frame. + /// + /// This value is used to determine which rulers are rarely used and should be + /// evicted from the ruler cache. + int get hitCount => _hitCount; + int _hitCount = 0; + + /// Resets the hit count back to zero. + void resetHitCount() { + _hitCount = 0; + } + + /// Makes sure this ruler is not used again after it has been disposed of, + /// which would indicate a bug. + bool get debugIsDisposed => _debugIsDisposed; + bool _debugIsDisposed = false; + + void _configureSingleLineHostElements() { + _singleLineHost.style + ..visibility = 'hidden' + ..position = 'absolute' + ..top = '0' // this is important as baseline == probe.bottom + ..left = '0' + ..display = 'flex' + ..flexDirection = 'row' + ..alignItems = 'baseline' + ..margin = '0' + ..border = '0' + ..padding = '0'; + + singleLineDimensions.applyStyle(style); + + // Force single-line (even if wider than screen) and preserve whitespaces. + singleLineDimensions._element.style.whiteSpace = 'pre'; + + singleLineDimensions.appendToHost(_singleLineHost); + TextMeasurementService.instance.addHostElement(_singleLineHost); + } + + void _configureMinIntrinsicHostElements() { + // Configure min intrinsic host elements. + _minIntrinsicHost.style + ..visibility = 'hidden' + ..position = 'absolute' + ..top = '0' // this is important as baseline == probe.bottom + ..left = '0' + ..display = 'flex' + ..flexDirection = 'row' + ..margin = '0' + ..border = '0' + ..padding = '0'; + + minIntrinsicDimensions.applyStyle(style); + + // "flex: 0" causes the paragraph element to shrink horizontally, exposing + // its minimum intrinsic width. + minIntrinsicDimensions._element.style + ..flex = '0' + ..display = 'inline' + // Preserve whitespaces. + ..whiteSpace = 'pre-wrap'; + + _minIntrinsicHost.append(minIntrinsicDimensions._element); + TextMeasurementService.instance.addHostElement(_minIntrinsicHost); + } + + void _configureConstrainedHostElements() { + _constrainedHost.style + ..visibility = 'hidden' + ..position = 'absolute' + ..top = '0' // this is important as baseline == probe.bottom + ..left = '0' + ..display = 'flex' + ..flexDirection = 'row' + ..alignItems = 'baseline' + ..margin = '0' + ..border = '0' + ..padding = '0'; + + constrainedDimensions.applyStyle(style); + constrainedDimensions._element.style + ..display = 'block' + // Preserve whitespaces. + ..whiteSpace = 'pre-wrap'; + + constrainedDimensions.appendToHost(_constrainedHost); + TextMeasurementService.instance.addHostElement(_constrainedHost); + } + + void _configureLineHeightHostElements() { + _lineHeightHost.style + ..visibility = 'hidden' + ..position = 'absolute' + ..top = '0' + ..left = '0' + ..margin = '0' + ..border = '0' + ..padding = '0'; + + lineHeightDimensions.applyStyle(style); + + // Force single-line (even if wider than screen) and preserve whitespaces. + lineHeightDimensions._element.style.whiteSpace = 'pre'; + + // To measure line-height, all we need is a whitespace. + lineHeightDimensions.updateTextToSpace(); + + lineHeightDimensions.appendToHost(_lineHeightHost); + TextMeasurementService.instance.addHostElement(_lineHeightHost); + } + + /// The paragraph being measured. + ui.Paragraph _paragraph; + + /// Prepares this ruler for measuring the given [paragraph]. + /// + /// This method must be called before calling any of the `measure*` methods. + void willMeasure(ui.Paragraph paragraph) { + assert(paragraph != null); + assert(() { + if (_paragraph != null) { + throw Exception( + 'Attempted to reuse a $ParagraphRuler but it is currently ' + 'measuring another paragraph ($_paragraph). It is possible that '); + } + return true; + }()); + assert(paragraph.webOnlyDebugHasSameRootStyle(style)); + _hitCount += 1; + _paragraph = paragraph; + } + + /// Prepares all 3 measurements: + /// 1. single line. + /// 2. minimum intrinsic width. + /// 3. constrained. + void measureAll(ui.ParagraphConstraints constraints) { + measureAsSingleLine(); + measureMinIntrinsicWidth(); + measureWithConstraints(constraints); + } + + /// Lays out the paragraph in a single line, giving it infinite amount of + /// horizontal space. + /// + /// Measures [width], [height], and [alphabeticBaseline]. + void measureAsSingleLine() { + assert(!_debugIsDisposed); + assert(_paragraph != null); + + // HACK(mdebbar): TextField uses an empty string to measure the line height, + // which doesn't work. So we need to replace it with a whitespace. The + // correct fix would be to do line height and baseline measurements and + // cache them separately. + if (_paragraph.webOnlyGetPlainText() == '') { + singleLineDimensions.updateTextToSpace(); + } else { + singleLineDimensions.updateText(_paragraph, style); + } + } + + /// Lays out the paragraph inside a flex row and sets "flex: 0", which + /// squeezes the paragraph, forcing it to occupy minimum intrinsic width. + /// + /// Measures [width] and [height]. + void measureMinIntrinsicWidth() { + assert(!_debugIsDisposed); + assert(_paragraph != null); + + minIntrinsicDimensions.updateText(_paragraph, style); + } + + /// Lays out the paragraph giving it a width constraint. + /// + /// Measures [width], [height], and [alphabeticBaseline]. + void measureWithConstraints(ui.ParagraphConstraints constraints) { + assert(!_debugIsDisposed); + assert(_paragraph != null); + + constrainedDimensions.updateText(_paragraph, style); + + // The extra 0.5 is because sometimes the browser needs slightly more space + // than the size it reports back. When that happens the text may be wrap + // when we thought it didn't. + constrainedDimensions.updateWidth('${constraints.width + 0.5}px'); + } + + /// Performs clean-up after a measurement is done, preparing this ruler for + /// a future reuse. + /// + /// Call this method immediately after calling `measure*` methods for a + /// particular [paragraph]. This ruler is not reusable until [didMeasure] is + /// called. + void didMeasure() { + assert(_paragraph != null); + // Remove any rich text we set during layout for the following reasons: + // - there won't be any text for the browser to lay out when we commit the + // current frame. + // - this keeps the cost of removing content together with the measurement + // in the profile. Otherwise, the cost of removing will be paid by a + // random next paragraph measured in the future, and make the performance + // profile hard to understand. + // + // We do not do this for plain text, because replacing plain text is more + // expensive than paying the cost of the DOM mutation to clean it. + if (_paragraph.webOnlyGetPlainText() == null) { + domRenderer + ..clearDom(singleLineDimensions._element) + ..clearDom(minIntrinsicDimensions._element) + ..clearDom(constrainedDimensions._element); + } + _paragraph = null; + } + + /// Performs stateless measurement of text boxes for a given range of text. + /// + /// This method doesn't depend on [willMeasure] and [didMeasure] lifecycle + /// methods. + List measureBoxesForRange( + String plainText, + ui.ParagraphConstraints constraints, { + int start, + int end, + double alignOffset, + ui.TextDirection textDirection, + }) { + assert(!_debugIsDisposed); + assert(start >= 0 && start <= plainText.length); + assert(end >= 0 && end <= plainText.length); + assert(start <= end); + + final String before = plainText.substring(0, start); + final String rangeText = plainText.substring(start, end); + final String after = plainText.substring(end); + + final html.SpanElement rangeSpan = html.SpanElement()..text = rangeText; + + // Setup the [ruler.constrainedDimensions] element to be used for measurement. + domRenderer.clearDom(constrainedDimensions._element); + constrainedDimensions._element + ..appendText(before) + ..append(rangeSpan) + ..appendText(after); + constrainedDimensions.updateWidth('${constraints.width}px'); + + // Measure the rects of [rangeSpan]. + final List> clientRects = rangeSpan.getClientRects(); + final List boxes = []; + + for (html.Rectangle rect in clientRects) { + boxes.add(ui.TextBox.fromLTRBD( + rect.left + alignOffset, + rect.top, + rect.right + alignOffset, + rect.bottom, + textDirection, + )); + } + + // Cleanup after measuring the boxes. + domRenderer.clearDom(constrainedDimensions._element); + return boxes; + } + + /// Detaches this ruler from the DOM and makes it unusable for future + /// measurements. + /// + /// Disposed rulers should be garbage collected after calling this method. + void dispose() { + assert(() { + if (_paragraph != null) { + throw Exception('Attempted to dispose of a ruler in the middle of ' + 'measurement. This is likely a bug in the framework.'); + } + return true; + }()); + _singleLineHost.remove(); + _minIntrinsicHost.remove(); + _constrainedHost.remove(); + _lineHeightHost?.remove(); + assert(() { + _debugIsDisposed = true; + return true; + }()); + } + + // Bounded cache for text measurement for a particular width constraint. + Map> _measurementCache = + Map>(); + // Mru list for cache. + final List _mruList = []; + static const int _cacheLimit = 2400; + // Number of items to evict when cache limit is reached. + static const int _cacheBlockFactor = 100; + // Number of constraint results per unique text item. + // This limit prevents growth during animation where the size of a container + // is changing. + static const int _constraintCacheSize = 8; + + void cacheMeasurement(ui.Paragraph paragraph, + ui.ParagraphConstraints constraints, RulerCacheEntry item) { + final plainText = paragraph.webOnlyGetPlainText(); + List constraintCache = _measurementCache[plainText]; + if (constraintCache == null) { + constraintCache = _measurementCache[plainText] = List(); + } + constraintCache.add(item); + if (constraintCache.length > _constraintCacheSize) { + constraintCache.removeAt(0); + } + _mruList.add(plainText); + if (_mruList.length > _cacheLimit) { + // Evict a range. + for (int i = 0; i < _cacheBlockFactor; i++) { + _measurementCache.remove(_mruList[i]); + } + _mruList.removeRange(0, _cacheBlockFactor); + } + } + + RulerCacheEntry cacheLookup( + ui.Paragraph paragraph, ui.ParagraphConstraints constraints) { + List constraintCache = + _measurementCache[paragraph.webOnlyGetPlainText()]; + if (constraintCache == null) { + return null; + } + for (int i = 0, len = constraintCache.length; i < len; i++) { + RulerCacheEntry item = constraintCache[i]; + if (item.constraintWidth == constraints.width) { + return item; + } + } + return null; + } +} + +/// Item used to cache mru measurements. +class RulerCacheEntry { + final double constraintWidth; + final bool isSingleLine; + final double width; + final double height; + final double lineHeight; + final double minIntrinsicWidth; + final double maxIntrinsicWidth; + final double alphabeticBaseline; + final double ideographicBaseline; + + RulerCacheEntry(this.constraintWidth, + {this.isSingleLine, + this.width, + this.height, + this.lineHeight, + this.minIntrinsicWidth, + this.maxIntrinsicWidth, + this.alphabeticBaseline, + this.ideographicBaseline}); + + void applyToParagraph(ui.Paragraph paragraph) { + paragraph.webOnlySetComputedLayout( + isSingleLine: isSingleLine, + width: width, + height: height, + lineHeight: lineHeight, + minIntrinsicWidth: minIntrinsicWidth, + maxIntrinsicWidth: maxIntrinsicWidth, + alphabeticBaseline: alphabeticBaseline, + ideographicBaseline: ideographicBaseline); + } +} diff --git a/lib/stub_ui/lib/src/engine/text/unicode_range.dart b/lib/stub_ui/lib/src/engine/text/unicode_range.dart new file mode 100644 index 0000000000000..f1979eeab981c --- /dev/null +++ b/lib/stub_ui/lib/src/engine/text/unicode_range.dart @@ -0,0 +1,95 @@ +// 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. + +part of engine; + +enum _ComparisonResult { + inside, + higher, + lower, +} + +/// Each instance of [UnicodeRange] represents a range of unicode characters +/// that are assigned a [CharProperty]. For example, the following snippet: +/// +/// ```dart +/// UnicodeRange(0x0041, 0x005A, CharProperty.ALetter); +/// ``` +/// +/// is saying that all characters between 0x0041 ("A") and 0x005A ("Z") are +/// assigned the property [CharProperty.ALetter]. +/// +/// Note that the Unicode spec uses inclusive ranges and we are doing the +/// same here. +class UnicodeRange

{ + const UnicodeRange(this.start, this.end, this.property); + + final int start; + + final int end; + + final P property; + + /// Compare a [value] to this range. + /// + /// The return value is either: + /// - lower: The value is lower than the range. + /// - higher: The value is higher than the range + /// - inside: The value is within the range. + _ComparisonResult compare(int value) { + if (value < start) return _ComparisonResult.lower; + if (value > end) return _ComparisonResult.higher; + return _ComparisonResult.inside; + } +} + +/// Given a list of [UnicodeRange]s, this class performs efficient lookup +/// to find which range a value falls into. +/// +/// The lookup algorithm expects the ranges to have the following constraints: +/// - Be sorted. +/// - No overlap between the ranges. +/// - Gaps between ranges are ok. +/// +/// This is used in the context of unicode to find out what property a letter +/// has. The properties are then used to decide word boundaries, line break +/// opportunities, etc. +class UnicodePropertyLookup

{ + const UnicodePropertyLookup(this.ranges); + + final List> ranges; + + P find(int value) { + final int index = _binarySearch(ranges, value, (a, b) { + final UnicodeRange

range = a; + switch (range.compare(b)) { + case _ComparisonResult.higher: + return -1; + case _ComparisonResult.lower: + return 1; + case _ComparisonResult.inside: + return 0; + } + }); + return index == -1 ? null : ranges[index].property; + } + + static int _binarySearch( + List sortedList, T value, int compare(T a, T b)) { + int min = 0; + int max = sortedList.length; + while (min < max) { + int mid = min + ((max - min) >> 1); + var element = sortedList[mid]; + int comp = compare(element, value); + if (comp == 0) return mid; + if (comp < 0) { + min = mid + 1; + } else { + max = mid; + } + } + return -1; + } +} diff --git a/lib/stub_ui/lib/src/engine/text/word_break_properties.dart b/lib/stub_ui/lib/src/engine/text/word_break_properties.dart new file mode 100644 index 0000000000000..f6504c5efa70c --- /dev/null +++ b/lib/stub_ui/lib/src/engine/text/word_break_properties.dart @@ -0,0 +1,996 @@ +// 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. + +// AUTO-GENERATED FILE. +// Generated by: bin/unicode_sync_script.dart +// +// Source: +// # WordBreakProperty-11.0.0.txt +// # Date: 2018-05-17, 00:51:53 GMT +// # © 2018 Unicode®, Inc. +// # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +// # For terms of use, see http://www.unicode.org/terms_of_use.html +// # +// # Unicode Character Database +// # For documentation, see http://www.unicode.org/reports/tr44/ + +part of engine; + +CharProperty getCharProperty(String text, int index) { + if (index < 0 || index >= text.length) { + return null; + } + return lookup.find(text.codeUnitAt(index)); +} + +enum CharProperty { + DoubleQuote, + SingleQuote, + HebrewLetter, + CR, + LF, + Newline, + Extend, + RegionalIndicator, + Format, + Katakana, + ALetter, + MidLetter, + MidNum, + MidNumLet, + Numeric, + ExtendNumLet, + ZWJ, + WSegSpace +} + +const UnicodePropertyLookup lookup = + UnicodePropertyLookup([ + UnicodeRange(0x000A, 0x000A, CharProperty.LF), + UnicodeRange(0x000B, 0x000C, CharProperty.Newline), + UnicodeRange(0x000D, 0x000D, CharProperty.CR), + UnicodeRange(0x0020, 0x0020, CharProperty.WSegSpace), + UnicodeRange(0x0022, 0x0022, CharProperty.DoubleQuote), + UnicodeRange(0x0027, 0x0027, CharProperty.SingleQuote), + UnicodeRange(0x002C, 0x002C, CharProperty.MidNum), + UnicodeRange(0x002E, 0x002E, CharProperty.MidNumLet), + UnicodeRange(0x0030, 0x0039, CharProperty.Numeric), + UnicodeRange(0x003A, 0x003A, CharProperty.MidLetter), + UnicodeRange(0x003B, 0x003B, CharProperty.MidNum), + UnicodeRange(0x0041, 0x005A, CharProperty.ALetter), + UnicodeRange(0x005F, 0x005F, CharProperty.ExtendNumLet), + UnicodeRange(0x0061, 0x007A, CharProperty.ALetter), + UnicodeRange(0x0085, 0x0085, CharProperty.Newline), + UnicodeRange(0x00AA, 0x00AA, CharProperty.ALetter), + UnicodeRange(0x00AD, 0x00AD, CharProperty.Format), + UnicodeRange(0x00B5, 0x00B5, CharProperty.ALetter), + UnicodeRange(0x00B7, 0x00B7, CharProperty.MidLetter), + UnicodeRange(0x00BA, 0x00BA, CharProperty.ALetter), + UnicodeRange(0x00C0, 0x00D6, CharProperty.ALetter), + UnicodeRange(0x00D8, 0x00F6, CharProperty.ALetter), + UnicodeRange(0x00F8, 0x02D7, CharProperty.ALetter), + UnicodeRange(0x02DE, 0x02E4, CharProperty.ALetter), + UnicodeRange(0x02EC, 0x02FF, CharProperty.ALetter), + UnicodeRange(0x0300, 0x036F, CharProperty.Extend), + UnicodeRange(0x0370, 0x0374, CharProperty.ALetter), + UnicodeRange(0x0376, 0x0377, CharProperty.ALetter), + UnicodeRange(0x037A, 0x037D, CharProperty.ALetter), + UnicodeRange(0x037E, 0x037E, CharProperty.MidNum), + UnicodeRange(0x037F, 0x037F, CharProperty.ALetter), + UnicodeRange(0x0386, 0x0386, CharProperty.ALetter), + UnicodeRange(0x0387, 0x0387, CharProperty.MidLetter), + UnicodeRange(0x0388, 0x038A, CharProperty.ALetter), + UnicodeRange(0x038C, 0x038C, CharProperty.ALetter), + UnicodeRange(0x038E, 0x03A1, CharProperty.ALetter), + UnicodeRange(0x03A3, 0x03F5, CharProperty.ALetter), + UnicodeRange(0x03F7, 0x0481, CharProperty.ALetter), + UnicodeRange(0x0483, 0x0489, CharProperty.Extend), + UnicodeRange(0x048A, 0x052F, CharProperty.ALetter), + UnicodeRange(0x0531, 0x0556, CharProperty.ALetter), + UnicodeRange(0x0559, 0x0559, CharProperty.ALetter), + UnicodeRange(0x055B, 0x055C, CharProperty.ALetter), + UnicodeRange(0x055E, 0x055E, CharProperty.ALetter), + UnicodeRange(0x0560, 0x0588, CharProperty.ALetter), + UnicodeRange(0x0589, 0x0589, CharProperty.MidNum), + UnicodeRange(0x0591, 0x05BD, CharProperty.Extend), + UnicodeRange(0x05BF, 0x05BF, CharProperty.Extend), + UnicodeRange(0x05C1, 0x05C2, CharProperty.Extend), + UnicodeRange(0x05C4, 0x05C5, CharProperty.Extend), + UnicodeRange(0x05C7, 0x05C7, CharProperty.Extend), + UnicodeRange(0x05D0, 0x05EA, CharProperty.HebrewLetter), + UnicodeRange(0x05EF, 0x05F2, CharProperty.HebrewLetter), + UnicodeRange(0x05F3, 0x05F3, CharProperty.ALetter), + UnicodeRange(0x05F4, 0x05F4, CharProperty.MidLetter), + UnicodeRange(0x0600, 0x0605, CharProperty.Format), + UnicodeRange(0x060C, 0x060D, CharProperty.MidNum), + UnicodeRange(0x0610, 0x061A, CharProperty.Extend), + UnicodeRange(0x061C, 0x061C, CharProperty.Format), + UnicodeRange(0x0620, 0x064A, CharProperty.ALetter), + UnicodeRange(0x064B, 0x065F, CharProperty.Extend), + UnicodeRange(0x0660, 0x0669, CharProperty.Numeric), + UnicodeRange(0x066B, 0x066B, CharProperty.Numeric), + UnicodeRange(0x066C, 0x066C, CharProperty.MidNum), + UnicodeRange(0x066E, 0x066F, CharProperty.ALetter), + UnicodeRange(0x0670, 0x0670, CharProperty.Extend), + UnicodeRange(0x0671, 0x06D3, CharProperty.ALetter), + UnicodeRange(0x06D5, 0x06D5, CharProperty.ALetter), + UnicodeRange(0x06D6, 0x06DC, CharProperty.Extend), + UnicodeRange(0x06DD, 0x06DD, CharProperty.Format), + UnicodeRange(0x06DF, 0x06E4, CharProperty.Extend), + UnicodeRange(0x06E5, 0x06E6, CharProperty.ALetter), + UnicodeRange(0x06E7, 0x06E8, CharProperty.Extend), + UnicodeRange(0x06EA, 0x06ED, CharProperty.Extend), + UnicodeRange(0x06EE, 0x06EF, CharProperty.ALetter), + UnicodeRange(0x06F0, 0x06F9, CharProperty.Numeric), + UnicodeRange(0x06FA, 0x06FC, CharProperty.ALetter), + UnicodeRange(0x06FF, 0x06FF, CharProperty.ALetter), + UnicodeRange(0x070F, 0x070F, CharProperty.Format), + UnicodeRange(0x0710, 0x0710, CharProperty.ALetter), + UnicodeRange(0x0711, 0x0711, CharProperty.Extend), + UnicodeRange(0x0712, 0x072F, CharProperty.ALetter), + UnicodeRange(0x0730, 0x074A, CharProperty.Extend), + UnicodeRange(0x074D, 0x07A5, CharProperty.ALetter), + UnicodeRange(0x07A6, 0x07B0, CharProperty.Extend), + UnicodeRange(0x07B1, 0x07B1, CharProperty.ALetter), + UnicodeRange(0x07C0, 0x07C9, CharProperty.Numeric), + UnicodeRange(0x07CA, 0x07EA, CharProperty.ALetter), + UnicodeRange(0x07EB, 0x07F3, CharProperty.Extend), + UnicodeRange(0x07F4, 0x07F5, CharProperty.ALetter), + UnicodeRange(0x07F8, 0x07F8, CharProperty.MidNum), + UnicodeRange(0x07FA, 0x07FA, CharProperty.ALetter), + UnicodeRange(0x07FD, 0x07FD, CharProperty.Extend), + UnicodeRange(0x0800, 0x0815, CharProperty.ALetter), + UnicodeRange(0x0816, 0x0819, CharProperty.Extend), + UnicodeRange(0x081A, 0x081A, CharProperty.ALetter), + UnicodeRange(0x081B, 0x0823, CharProperty.Extend), + UnicodeRange(0x0824, 0x0824, CharProperty.ALetter), + UnicodeRange(0x0825, 0x0827, CharProperty.Extend), + UnicodeRange(0x0828, 0x0828, CharProperty.ALetter), + UnicodeRange(0x0829, 0x082D, CharProperty.Extend), + UnicodeRange(0x0840, 0x0858, CharProperty.ALetter), + UnicodeRange(0x0859, 0x085B, CharProperty.Extend), + UnicodeRange(0x0860, 0x086A, CharProperty.ALetter), + UnicodeRange(0x08A0, 0x08B4, CharProperty.ALetter), + UnicodeRange(0x08B6, 0x08BD, CharProperty.ALetter), + UnicodeRange(0x08D3, 0x08E1, CharProperty.Extend), + UnicodeRange(0x08E2, 0x08E2, CharProperty.Format), + UnicodeRange(0x08E3, 0x0903, CharProperty.Extend), + UnicodeRange(0x0904, 0x0939, CharProperty.ALetter), + UnicodeRange(0x093A, 0x093C, CharProperty.Extend), + UnicodeRange(0x093D, 0x093D, CharProperty.ALetter), + UnicodeRange(0x093E, 0x094F, CharProperty.Extend), + UnicodeRange(0x0950, 0x0950, CharProperty.ALetter), + UnicodeRange(0x0951, 0x0957, CharProperty.Extend), + UnicodeRange(0x0958, 0x0961, CharProperty.ALetter), + UnicodeRange(0x0962, 0x0963, CharProperty.Extend), + UnicodeRange(0x0966, 0x096F, CharProperty.Numeric), + UnicodeRange(0x0971, 0x0980, CharProperty.ALetter), + UnicodeRange(0x0981, 0x0983, CharProperty.Extend), + UnicodeRange(0x0985, 0x098C, CharProperty.ALetter), + UnicodeRange(0x098F, 0x0990, CharProperty.ALetter), + UnicodeRange(0x0993, 0x09A8, CharProperty.ALetter), + UnicodeRange(0x09AA, 0x09B0, CharProperty.ALetter), + UnicodeRange(0x09B2, 0x09B2, CharProperty.ALetter), + UnicodeRange(0x09B6, 0x09B9, CharProperty.ALetter), + UnicodeRange(0x09BC, 0x09BC, CharProperty.Extend), + UnicodeRange(0x09BD, 0x09BD, CharProperty.ALetter), + UnicodeRange(0x09BE, 0x09C4, CharProperty.Extend), + UnicodeRange(0x09C7, 0x09C8, CharProperty.Extend), + UnicodeRange(0x09CB, 0x09CD, CharProperty.Extend), + UnicodeRange(0x09CE, 0x09CE, CharProperty.ALetter), + UnicodeRange(0x09D7, 0x09D7, CharProperty.Extend), + UnicodeRange(0x09DC, 0x09DD, CharProperty.ALetter), + UnicodeRange(0x09DF, 0x09E1, CharProperty.ALetter), + UnicodeRange(0x09E2, 0x09E3, CharProperty.Extend), + UnicodeRange(0x09E6, 0x09EF, CharProperty.Numeric), + UnicodeRange(0x09F0, 0x09F1, CharProperty.ALetter), + UnicodeRange(0x09FC, 0x09FC, CharProperty.ALetter), + UnicodeRange(0x09FE, 0x09FE, CharProperty.Extend), + UnicodeRange(0x0A01, 0x0A03, CharProperty.Extend), + UnicodeRange(0x0A05, 0x0A0A, CharProperty.ALetter), + UnicodeRange(0x0A0F, 0x0A10, CharProperty.ALetter), + UnicodeRange(0x0A13, 0x0A28, CharProperty.ALetter), + UnicodeRange(0x0A2A, 0x0A30, CharProperty.ALetter), + UnicodeRange(0x0A32, 0x0A33, CharProperty.ALetter), + UnicodeRange(0x0A35, 0x0A36, CharProperty.ALetter), + UnicodeRange(0x0A38, 0x0A39, CharProperty.ALetter), + UnicodeRange(0x0A3C, 0x0A3C, CharProperty.Extend), + UnicodeRange(0x0A3E, 0x0A42, CharProperty.Extend), + UnicodeRange(0x0A47, 0x0A48, CharProperty.Extend), + UnicodeRange(0x0A4B, 0x0A4D, CharProperty.Extend), + UnicodeRange(0x0A51, 0x0A51, CharProperty.Extend), + UnicodeRange(0x0A59, 0x0A5C, CharProperty.ALetter), + UnicodeRange(0x0A5E, 0x0A5E, CharProperty.ALetter), + UnicodeRange(0x0A66, 0x0A6F, CharProperty.Numeric), + UnicodeRange(0x0A70, 0x0A71, CharProperty.Extend), + UnicodeRange(0x0A72, 0x0A74, CharProperty.ALetter), + UnicodeRange(0x0A75, 0x0A75, CharProperty.Extend), + UnicodeRange(0x0A81, 0x0A83, CharProperty.Extend), + UnicodeRange(0x0A85, 0x0A8D, CharProperty.ALetter), + UnicodeRange(0x0A8F, 0x0A91, CharProperty.ALetter), + UnicodeRange(0x0A93, 0x0AA8, CharProperty.ALetter), + UnicodeRange(0x0AAA, 0x0AB0, CharProperty.ALetter), + UnicodeRange(0x0AB2, 0x0AB3, CharProperty.ALetter), + UnicodeRange(0x0AB5, 0x0AB9, CharProperty.ALetter), + UnicodeRange(0x0ABC, 0x0ABC, CharProperty.Extend), + UnicodeRange(0x0ABD, 0x0ABD, CharProperty.ALetter), + UnicodeRange(0x0ABE, 0x0AC5, CharProperty.Extend), + UnicodeRange(0x0AC7, 0x0AC9, CharProperty.Extend), + UnicodeRange(0x0ACB, 0x0ACD, CharProperty.Extend), + UnicodeRange(0x0AD0, 0x0AD0, CharProperty.ALetter), + UnicodeRange(0x0AE0, 0x0AE1, CharProperty.ALetter), + UnicodeRange(0x0AE2, 0x0AE3, CharProperty.Extend), + UnicodeRange(0x0AE6, 0x0AEF, CharProperty.Numeric), + UnicodeRange(0x0AF9, 0x0AF9, CharProperty.ALetter), + UnicodeRange(0x0AFA, 0x0AFF, CharProperty.Extend), + UnicodeRange(0x0B01, 0x0B03, CharProperty.Extend), + UnicodeRange(0x0B05, 0x0B0C, CharProperty.ALetter), + UnicodeRange(0x0B0F, 0x0B10, CharProperty.ALetter), + UnicodeRange(0x0B13, 0x0B28, CharProperty.ALetter), + UnicodeRange(0x0B2A, 0x0B30, CharProperty.ALetter), + UnicodeRange(0x0B32, 0x0B33, CharProperty.ALetter), + UnicodeRange(0x0B35, 0x0B39, CharProperty.ALetter), + UnicodeRange(0x0B3C, 0x0B3C, CharProperty.Extend), + UnicodeRange(0x0B3D, 0x0B3D, CharProperty.ALetter), + UnicodeRange(0x0B3E, 0x0B44, CharProperty.Extend), + UnicodeRange(0x0B47, 0x0B48, CharProperty.Extend), + UnicodeRange(0x0B4B, 0x0B4D, CharProperty.Extend), + UnicodeRange(0x0B56, 0x0B57, CharProperty.Extend), + UnicodeRange(0x0B5C, 0x0B5D, CharProperty.ALetter), + UnicodeRange(0x0B5F, 0x0B61, CharProperty.ALetter), + UnicodeRange(0x0B62, 0x0B63, CharProperty.Extend), + UnicodeRange(0x0B66, 0x0B6F, CharProperty.Numeric), + UnicodeRange(0x0B71, 0x0B71, CharProperty.ALetter), + UnicodeRange(0x0B82, 0x0B82, CharProperty.Extend), + UnicodeRange(0x0B83, 0x0B83, CharProperty.ALetter), + UnicodeRange(0x0B85, 0x0B8A, CharProperty.ALetter), + UnicodeRange(0x0B8E, 0x0B90, CharProperty.ALetter), + UnicodeRange(0x0B92, 0x0B95, CharProperty.ALetter), + UnicodeRange(0x0B99, 0x0B9A, CharProperty.ALetter), + UnicodeRange(0x0B9C, 0x0B9C, CharProperty.ALetter), + UnicodeRange(0x0B9E, 0x0B9F, CharProperty.ALetter), + UnicodeRange(0x0BA3, 0x0BA4, CharProperty.ALetter), + UnicodeRange(0x0BA8, 0x0BAA, CharProperty.ALetter), + UnicodeRange(0x0BAE, 0x0BB9, CharProperty.ALetter), + UnicodeRange(0x0BBE, 0x0BC2, CharProperty.Extend), + UnicodeRange(0x0BC6, 0x0BC8, CharProperty.Extend), + UnicodeRange(0x0BCA, 0x0BCD, CharProperty.Extend), + UnicodeRange(0x0BD0, 0x0BD0, CharProperty.ALetter), + UnicodeRange(0x0BD7, 0x0BD7, CharProperty.Extend), + UnicodeRange(0x0BE6, 0x0BEF, CharProperty.Numeric), + UnicodeRange(0x0C00, 0x0C04, CharProperty.Extend), + UnicodeRange(0x0C05, 0x0C0C, CharProperty.ALetter), + UnicodeRange(0x0C0E, 0x0C10, CharProperty.ALetter), + UnicodeRange(0x0C12, 0x0C28, CharProperty.ALetter), + UnicodeRange(0x0C2A, 0x0C39, CharProperty.ALetter), + UnicodeRange(0x0C3D, 0x0C3D, CharProperty.ALetter), + UnicodeRange(0x0C3E, 0x0C44, CharProperty.Extend), + UnicodeRange(0x0C46, 0x0C48, CharProperty.Extend), + UnicodeRange(0x0C4A, 0x0C4D, CharProperty.Extend), + UnicodeRange(0x0C55, 0x0C56, CharProperty.Extend), + UnicodeRange(0x0C58, 0x0C5A, CharProperty.ALetter), + UnicodeRange(0x0C60, 0x0C61, CharProperty.ALetter), + UnicodeRange(0x0C62, 0x0C63, CharProperty.Extend), + UnicodeRange(0x0C66, 0x0C6F, CharProperty.Numeric), + UnicodeRange(0x0C80, 0x0C80, CharProperty.ALetter), + UnicodeRange(0x0C81, 0x0C83, CharProperty.Extend), + UnicodeRange(0x0C85, 0x0C8C, CharProperty.ALetter), + UnicodeRange(0x0C8E, 0x0C90, CharProperty.ALetter), + UnicodeRange(0x0C92, 0x0CA8, CharProperty.ALetter), + UnicodeRange(0x0CAA, 0x0CB3, CharProperty.ALetter), + UnicodeRange(0x0CB5, 0x0CB9, CharProperty.ALetter), + UnicodeRange(0x0CBC, 0x0CBC, CharProperty.Extend), + UnicodeRange(0x0CBD, 0x0CBD, CharProperty.ALetter), + UnicodeRange(0x0CBE, 0x0CC4, CharProperty.Extend), + UnicodeRange(0x0CC6, 0x0CC8, CharProperty.Extend), + UnicodeRange(0x0CCA, 0x0CCD, CharProperty.Extend), + UnicodeRange(0x0CD5, 0x0CD6, CharProperty.Extend), + UnicodeRange(0x0CDE, 0x0CDE, CharProperty.ALetter), + UnicodeRange(0x0CE0, 0x0CE1, CharProperty.ALetter), + UnicodeRange(0x0CE2, 0x0CE3, CharProperty.Extend), + UnicodeRange(0x0CE6, 0x0CEF, CharProperty.Numeric), + UnicodeRange(0x0CF1, 0x0CF2, CharProperty.ALetter), + UnicodeRange(0x0D00, 0x0D03, CharProperty.Extend), + UnicodeRange(0x0D05, 0x0D0C, CharProperty.ALetter), + UnicodeRange(0x0D0E, 0x0D10, CharProperty.ALetter), + UnicodeRange(0x0D12, 0x0D3A, CharProperty.ALetter), + UnicodeRange(0x0D3B, 0x0D3C, CharProperty.Extend), + UnicodeRange(0x0D3D, 0x0D3D, CharProperty.ALetter), + UnicodeRange(0x0D3E, 0x0D44, CharProperty.Extend), + UnicodeRange(0x0D46, 0x0D48, CharProperty.Extend), + UnicodeRange(0x0D4A, 0x0D4D, CharProperty.Extend), + UnicodeRange(0x0D4E, 0x0D4E, CharProperty.ALetter), + UnicodeRange(0x0D54, 0x0D56, CharProperty.ALetter), + UnicodeRange(0x0D57, 0x0D57, CharProperty.Extend), + UnicodeRange(0x0D5F, 0x0D61, CharProperty.ALetter), + UnicodeRange(0x0D62, 0x0D63, CharProperty.Extend), + UnicodeRange(0x0D66, 0x0D6F, CharProperty.Numeric), + UnicodeRange(0x0D7A, 0x0D7F, CharProperty.ALetter), + UnicodeRange(0x0D82, 0x0D83, CharProperty.Extend), + UnicodeRange(0x0D85, 0x0D96, CharProperty.ALetter), + UnicodeRange(0x0D9A, 0x0DB1, CharProperty.ALetter), + UnicodeRange(0x0DB3, 0x0DBB, CharProperty.ALetter), + UnicodeRange(0x0DBD, 0x0DBD, CharProperty.ALetter), + UnicodeRange(0x0DC0, 0x0DC6, CharProperty.ALetter), + UnicodeRange(0x0DCA, 0x0DCA, CharProperty.Extend), + UnicodeRange(0x0DCF, 0x0DD4, CharProperty.Extend), + UnicodeRange(0x0DD6, 0x0DD6, CharProperty.Extend), + UnicodeRange(0x0DD8, 0x0DDF, CharProperty.Extend), + UnicodeRange(0x0DE6, 0x0DEF, CharProperty.Numeric), + UnicodeRange(0x0DF2, 0x0DF3, CharProperty.Extend), + UnicodeRange(0x0E31, 0x0E31, CharProperty.Extend), + UnicodeRange(0x0E34, 0x0E3A, CharProperty.Extend), + UnicodeRange(0x0E47, 0x0E4E, CharProperty.Extend), + UnicodeRange(0x0E50, 0x0E59, CharProperty.Numeric), + UnicodeRange(0x0EB1, 0x0EB1, CharProperty.Extend), + UnicodeRange(0x0EB4, 0x0EB9, CharProperty.Extend), + UnicodeRange(0x0EBB, 0x0EBC, CharProperty.Extend), + UnicodeRange(0x0EC8, 0x0ECD, CharProperty.Extend), + UnicodeRange(0x0ED0, 0x0ED9, CharProperty.Numeric), + UnicodeRange(0x0F00, 0x0F00, CharProperty.ALetter), + UnicodeRange(0x0F18, 0x0F19, CharProperty.Extend), + UnicodeRange(0x0F20, 0x0F29, CharProperty.Numeric), + UnicodeRange(0x0F35, 0x0F35, CharProperty.Extend), + UnicodeRange(0x0F37, 0x0F37, CharProperty.Extend), + UnicodeRange(0x0F39, 0x0F39, CharProperty.Extend), + UnicodeRange(0x0F3E, 0x0F3F, CharProperty.Extend), + UnicodeRange(0x0F40, 0x0F47, CharProperty.ALetter), + UnicodeRange(0x0F49, 0x0F6C, CharProperty.ALetter), + UnicodeRange(0x0F71, 0x0F84, CharProperty.Extend), + UnicodeRange(0x0F86, 0x0F87, CharProperty.Extend), + UnicodeRange(0x0F88, 0x0F8C, CharProperty.ALetter), + UnicodeRange(0x0F8D, 0x0F97, CharProperty.Extend), + UnicodeRange(0x0F99, 0x0FBC, CharProperty.Extend), + UnicodeRange(0x0FC6, 0x0FC6, CharProperty.Extend), + UnicodeRange(0x102B, 0x103E, CharProperty.Extend), + UnicodeRange(0x1040, 0x1049, CharProperty.Numeric), + UnicodeRange(0x1056, 0x1059, CharProperty.Extend), + UnicodeRange(0x105E, 0x1060, CharProperty.Extend), + UnicodeRange(0x1062, 0x1064, CharProperty.Extend), + UnicodeRange(0x1067, 0x106D, CharProperty.Extend), + UnicodeRange(0x1071, 0x1074, CharProperty.Extend), + UnicodeRange(0x1082, 0x108D, CharProperty.Extend), + UnicodeRange(0x108F, 0x108F, CharProperty.Extend), + UnicodeRange(0x1090, 0x1099, CharProperty.Numeric), + UnicodeRange(0x109A, 0x109D, CharProperty.Extend), + UnicodeRange(0x10A0, 0x10C5, CharProperty.ALetter), + UnicodeRange(0x10C7, 0x10C7, CharProperty.ALetter), + UnicodeRange(0x10CD, 0x10CD, CharProperty.ALetter), + UnicodeRange(0x10D0, 0x10FA, CharProperty.ALetter), + UnicodeRange(0x10FC, 0x1248, CharProperty.ALetter), + UnicodeRange(0x124A, 0x124D, CharProperty.ALetter), + UnicodeRange(0x1250, 0x1256, CharProperty.ALetter), + UnicodeRange(0x1258, 0x1258, CharProperty.ALetter), + UnicodeRange(0x125A, 0x125D, CharProperty.ALetter), + UnicodeRange(0x1260, 0x1288, CharProperty.ALetter), + UnicodeRange(0x128A, 0x128D, CharProperty.ALetter), + UnicodeRange(0x1290, 0x12B0, CharProperty.ALetter), + UnicodeRange(0x12B2, 0x12B5, CharProperty.ALetter), + UnicodeRange(0x12B8, 0x12BE, CharProperty.ALetter), + UnicodeRange(0x12C0, 0x12C0, CharProperty.ALetter), + UnicodeRange(0x12C2, 0x12C5, CharProperty.ALetter), + UnicodeRange(0x12C8, 0x12D6, CharProperty.ALetter), + UnicodeRange(0x12D8, 0x1310, CharProperty.ALetter), + UnicodeRange(0x1312, 0x1315, CharProperty.ALetter), + UnicodeRange(0x1318, 0x135A, CharProperty.ALetter), + UnicodeRange(0x135D, 0x135F, CharProperty.Extend), + UnicodeRange(0x1380, 0x138F, CharProperty.ALetter), + UnicodeRange(0x13A0, 0x13F5, CharProperty.ALetter), + UnicodeRange(0x13F8, 0x13FD, CharProperty.ALetter), + UnicodeRange(0x1401, 0x166C, CharProperty.ALetter), + UnicodeRange(0x166F, 0x167F, CharProperty.ALetter), + UnicodeRange(0x1680, 0x1680, CharProperty.WSegSpace), + UnicodeRange(0x1681, 0x169A, CharProperty.ALetter), + UnicodeRange(0x16A0, 0x16EA, CharProperty.ALetter), + UnicodeRange(0x16EE, 0x16F8, CharProperty.ALetter), + UnicodeRange(0x1700, 0x170C, CharProperty.ALetter), + UnicodeRange(0x170E, 0x1711, CharProperty.ALetter), + UnicodeRange(0x1712, 0x1714, CharProperty.Extend), + UnicodeRange(0x1720, 0x1731, CharProperty.ALetter), + UnicodeRange(0x1732, 0x1734, CharProperty.Extend), + UnicodeRange(0x1740, 0x1751, CharProperty.ALetter), + UnicodeRange(0x1752, 0x1753, CharProperty.Extend), + UnicodeRange(0x1760, 0x176C, CharProperty.ALetter), + UnicodeRange(0x176E, 0x1770, CharProperty.ALetter), + UnicodeRange(0x1772, 0x1773, CharProperty.Extend), + UnicodeRange(0x17B4, 0x17D3, CharProperty.Extend), + UnicodeRange(0x17DD, 0x17DD, CharProperty.Extend), + UnicodeRange(0x17E0, 0x17E9, CharProperty.Numeric), + UnicodeRange(0x180B, 0x180D, CharProperty.Extend), + UnicodeRange(0x180E, 0x180E, CharProperty.Format), + UnicodeRange(0x1810, 0x1819, CharProperty.Numeric), + UnicodeRange(0x1820, 0x1878, CharProperty.ALetter), + UnicodeRange(0x1880, 0x1884, CharProperty.ALetter), + UnicodeRange(0x1885, 0x1886, CharProperty.Extend), + UnicodeRange(0x1887, 0x18A8, CharProperty.ALetter), + UnicodeRange(0x18A9, 0x18A9, CharProperty.Extend), + UnicodeRange(0x18AA, 0x18AA, CharProperty.ALetter), + UnicodeRange(0x18B0, 0x18F5, CharProperty.ALetter), + UnicodeRange(0x1900, 0x191E, CharProperty.ALetter), + UnicodeRange(0x1920, 0x192B, CharProperty.Extend), + UnicodeRange(0x1930, 0x193B, CharProperty.Extend), + UnicodeRange(0x1946, 0x194F, CharProperty.Numeric), + UnicodeRange(0x19D0, 0x19D9, CharProperty.Numeric), + UnicodeRange(0x1A00, 0x1A16, CharProperty.ALetter), + UnicodeRange(0x1A17, 0x1A1B, CharProperty.Extend), + UnicodeRange(0x1A55, 0x1A5E, CharProperty.Extend), + UnicodeRange(0x1A60, 0x1A7C, CharProperty.Extend), + UnicodeRange(0x1A7F, 0x1A7F, CharProperty.Extend), + UnicodeRange(0x1A80, 0x1A89, CharProperty.Numeric), + UnicodeRange(0x1A90, 0x1A99, CharProperty.Numeric), + UnicodeRange(0x1AB0, 0x1ABE, CharProperty.Extend), + UnicodeRange(0x1B00, 0x1B04, CharProperty.Extend), + UnicodeRange(0x1B05, 0x1B33, CharProperty.ALetter), + UnicodeRange(0x1B34, 0x1B44, CharProperty.Extend), + UnicodeRange(0x1B45, 0x1B4B, CharProperty.ALetter), + UnicodeRange(0x1B50, 0x1B59, CharProperty.Numeric), + UnicodeRange(0x1B6B, 0x1B73, CharProperty.Extend), + UnicodeRange(0x1B80, 0x1B82, CharProperty.Extend), + UnicodeRange(0x1B83, 0x1BA0, CharProperty.ALetter), + UnicodeRange(0x1BA1, 0x1BAD, CharProperty.Extend), + UnicodeRange(0x1BAE, 0x1BAF, CharProperty.ALetter), + UnicodeRange(0x1BB0, 0x1BB9, CharProperty.Numeric), + UnicodeRange(0x1BBA, 0x1BE5, CharProperty.ALetter), + UnicodeRange(0x1BE6, 0x1BF3, CharProperty.Extend), + UnicodeRange(0x1C00, 0x1C23, CharProperty.ALetter), + UnicodeRange(0x1C24, 0x1C37, CharProperty.Extend), + UnicodeRange(0x1C40, 0x1C49, CharProperty.Numeric), + UnicodeRange(0x1C4D, 0x1C4F, CharProperty.ALetter), + UnicodeRange(0x1C50, 0x1C59, CharProperty.Numeric), + UnicodeRange(0x1C5A, 0x1C7D, CharProperty.ALetter), + UnicodeRange(0x1C80, 0x1C88, CharProperty.ALetter), + UnicodeRange(0x1C90, 0x1CBA, CharProperty.ALetter), + UnicodeRange(0x1CBD, 0x1CBF, CharProperty.ALetter), + UnicodeRange(0x1CD0, 0x1CD2, CharProperty.Extend), + UnicodeRange(0x1CD4, 0x1CE8, CharProperty.Extend), + UnicodeRange(0x1CE9, 0x1CEC, CharProperty.ALetter), + UnicodeRange(0x1CED, 0x1CED, CharProperty.Extend), + UnicodeRange(0x1CEE, 0x1CF1, CharProperty.ALetter), + UnicodeRange(0x1CF2, 0x1CF4, CharProperty.Extend), + UnicodeRange(0x1CF5, 0x1CF6, CharProperty.ALetter), + UnicodeRange(0x1CF7, 0x1CF9, CharProperty.Extend), + UnicodeRange(0x1D00, 0x1DBF, CharProperty.ALetter), + UnicodeRange(0x1DC0, 0x1DF9, CharProperty.Extend), + UnicodeRange(0x1DFB, 0x1DFF, CharProperty.Extend), + UnicodeRange(0x1E00, 0x1F15, CharProperty.ALetter), + UnicodeRange(0x1F18, 0x1F1D, CharProperty.ALetter), + UnicodeRange(0x1F20, 0x1F45, CharProperty.ALetter), + UnicodeRange(0x1F48, 0x1F4D, CharProperty.ALetter), + UnicodeRange(0x1F50, 0x1F57, CharProperty.ALetter), + UnicodeRange(0x1F59, 0x1F59, CharProperty.ALetter), + UnicodeRange(0x1F5B, 0x1F5B, CharProperty.ALetter), + UnicodeRange(0x1F5D, 0x1F5D, CharProperty.ALetter), + UnicodeRange(0x1F5F, 0x1F7D, CharProperty.ALetter), + UnicodeRange(0x1F80, 0x1FB4, CharProperty.ALetter), + UnicodeRange(0x1FB6, 0x1FBC, CharProperty.ALetter), + UnicodeRange(0x1FBE, 0x1FBE, CharProperty.ALetter), + UnicodeRange(0x1FC2, 0x1FC4, CharProperty.ALetter), + UnicodeRange(0x1FC6, 0x1FCC, CharProperty.ALetter), + UnicodeRange(0x1FD0, 0x1FD3, CharProperty.ALetter), + UnicodeRange(0x1FD6, 0x1FDB, CharProperty.ALetter), + UnicodeRange(0x1FE0, 0x1FEC, CharProperty.ALetter), + UnicodeRange(0x1FF2, 0x1FF4, CharProperty.ALetter), + UnicodeRange(0x1FF6, 0x1FFC, CharProperty.ALetter), + UnicodeRange(0x2000, 0x2006, CharProperty.WSegSpace), + UnicodeRange(0x2008, 0x200A, CharProperty.WSegSpace), + UnicodeRange(0x200C, 0x200C, CharProperty.Extend), + UnicodeRange(0x200D, 0x200D, CharProperty.ZWJ), + UnicodeRange(0x200E, 0x200F, CharProperty.Format), + UnicodeRange(0x2018, 0x2019, CharProperty.MidNumLet), + UnicodeRange(0x2024, 0x2024, CharProperty.MidNumLet), + UnicodeRange(0x2027, 0x2027, CharProperty.MidLetter), + UnicodeRange(0x2028, 0x2029, CharProperty.Newline), + UnicodeRange(0x202A, 0x202E, CharProperty.Format), + UnicodeRange(0x202F, 0x202F, CharProperty.ExtendNumLet), + UnicodeRange(0x203F, 0x2040, CharProperty.ExtendNumLet), + UnicodeRange(0x2044, 0x2044, CharProperty.MidNum), + UnicodeRange(0x2054, 0x2054, CharProperty.ExtendNumLet), + UnicodeRange(0x205F, 0x205F, CharProperty.WSegSpace), + UnicodeRange(0x2060, 0x2064, CharProperty.Format), + UnicodeRange(0x2066, 0x206F, CharProperty.Format), + UnicodeRange(0x2071, 0x2071, CharProperty.ALetter), + UnicodeRange(0x207F, 0x207F, CharProperty.ALetter), + UnicodeRange(0x2090, 0x209C, CharProperty.ALetter), + UnicodeRange(0x20D0, 0x20F0, CharProperty.Extend), + UnicodeRange(0x2102, 0x2102, CharProperty.ALetter), + UnicodeRange(0x2107, 0x2107, CharProperty.ALetter), + UnicodeRange(0x210A, 0x2113, CharProperty.ALetter), + UnicodeRange(0x2115, 0x2115, CharProperty.ALetter), + UnicodeRange(0x2119, 0x211D, CharProperty.ALetter), + UnicodeRange(0x2124, 0x2124, CharProperty.ALetter), + UnicodeRange(0x2126, 0x2126, CharProperty.ALetter), + UnicodeRange(0x2128, 0x2128, CharProperty.ALetter), + UnicodeRange(0x212A, 0x212D, CharProperty.ALetter), + UnicodeRange(0x212F, 0x2139, CharProperty.ALetter), + UnicodeRange(0x213C, 0x213F, CharProperty.ALetter), + UnicodeRange(0x2145, 0x2149, CharProperty.ALetter), + UnicodeRange(0x214E, 0x214E, CharProperty.ALetter), + UnicodeRange(0x2160, 0x2188, CharProperty.ALetter), + UnicodeRange(0x24B6, 0x24E9, CharProperty.ALetter), + UnicodeRange(0x2C00, 0x2C2E, CharProperty.ALetter), + UnicodeRange(0x2C30, 0x2C5E, CharProperty.ALetter), + UnicodeRange(0x2C60, 0x2CE4, CharProperty.ALetter), + UnicodeRange(0x2CEB, 0x2CEE, CharProperty.ALetter), + UnicodeRange(0x2CEF, 0x2CF1, CharProperty.Extend), + UnicodeRange(0x2CF2, 0x2CF3, CharProperty.ALetter), + UnicodeRange(0x2D00, 0x2D25, CharProperty.ALetter), + UnicodeRange(0x2D27, 0x2D27, CharProperty.ALetter), + UnicodeRange(0x2D2D, 0x2D2D, CharProperty.ALetter), + UnicodeRange(0x2D30, 0x2D67, CharProperty.ALetter), + UnicodeRange(0x2D6F, 0x2D6F, CharProperty.ALetter), + UnicodeRange(0x2D7F, 0x2D7F, CharProperty.Extend), + UnicodeRange(0x2D80, 0x2D96, CharProperty.ALetter), + UnicodeRange(0x2DA0, 0x2DA6, CharProperty.ALetter), + UnicodeRange(0x2DA8, 0x2DAE, CharProperty.ALetter), + UnicodeRange(0x2DB0, 0x2DB6, CharProperty.ALetter), + UnicodeRange(0x2DB8, 0x2DBE, CharProperty.ALetter), + UnicodeRange(0x2DC0, 0x2DC6, CharProperty.ALetter), + UnicodeRange(0x2DC8, 0x2DCE, CharProperty.ALetter), + UnicodeRange(0x2DD0, 0x2DD6, CharProperty.ALetter), + UnicodeRange(0x2DD8, 0x2DDE, CharProperty.ALetter), + UnicodeRange(0x2DE0, 0x2DFF, CharProperty.Extend), + UnicodeRange(0x2E2F, 0x2E2F, CharProperty.ALetter), + UnicodeRange(0x3000, 0x3000, CharProperty.WSegSpace), + UnicodeRange(0x3005, 0x3005, CharProperty.ALetter), + UnicodeRange(0x302A, 0x302F, CharProperty.Extend), + UnicodeRange(0x3031, 0x3035, CharProperty.Katakana), + UnicodeRange(0x303B, 0x303C, CharProperty.ALetter), + UnicodeRange(0x3099, 0x309A, CharProperty.Extend), + UnicodeRange(0x309B, 0x309C, CharProperty.Katakana), + UnicodeRange(0x30A0, 0x30FA, CharProperty.Katakana), + UnicodeRange(0x30FC, 0x30FF, CharProperty.Katakana), + UnicodeRange(0x3105, 0x312F, CharProperty.ALetter), + UnicodeRange(0x3131, 0x318E, CharProperty.ALetter), + UnicodeRange(0x31A0, 0x31BA, CharProperty.ALetter), + UnicodeRange(0x31F0, 0x31FF, CharProperty.Katakana), + UnicodeRange(0x32D0, 0x32FE, CharProperty.Katakana), + UnicodeRange(0x3300, 0x3357, CharProperty.Katakana), + UnicodeRange(0xA000, 0xA48C, CharProperty.ALetter), + UnicodeRange(0xA4D0, 0xA4FD, CharProperty.ALetter), + UnicodeRange(0xA500, 0xA60C, CharProperty.ALetter), + UnicodeRange(0xA610, 0xA61F, CharProperty.ALetter), + UnicodeRange(0xA620, 0xA629, CharProperty.Numeric), + UnicodeRange(0xA62A, 0xA62B, CharProperty.ALetter), + UnicodeRange(0xA640, 0xA66E, CharProperty.ALetter), + UnicodeRange(0xA66F, 0xA672, CharProperty.Extend), + UnicodeRange(0xA674, 0xA67D, CharProperty.Extend), + UnicodeRange(0xA67F, 0xA69D, CharProperty.ALetter), + UnicodeRange(0xA69E, 0xA69F, CharProperty.Extend), + UnicodeRange(0xA6A0, 0xA6EF, CharProperty.ALetter), + UnicodeRange(0xA6F0, 0xA6F1, CharProperty.Extend), + UnicodeRange(0xA717, 0xA7B9, CharProperty.ALetter), + UnicodeRange(0xA7F7, 0xA801, CharProperty.ALetter), + UnicodeRange(0xA802, 0xA802, CharProperty.Extend), + UnicodeRange(0xA803, 0xA805, CharProperty.ALetter), + UnicodeRange(0xA806, 0xA806, CharProperty.Extend), + UnicodeRange(0xA807, 0xA80A, CharProperty.ALetter), + UnicodeRange(0xA80B, 0xA80B, CharProperty.Extend), + UnicodeRange(0xA80C, 0xA822, CharProperty.ALetter), + UnicodeRange(0xA823, 0xA827, CharProperty.Extend), + UnicodeRange(0xA840, 0xA873, CharProperty.ALetter), + UnicodeRange(0xA880, 0xA881, CharProperty.Extend), + UnicodeRange(0xA882, 0xA8B3, CharProperty.ALetter), + UnicodeRange(0xA8B4, 0xA8C5, CharProperty.Extend), + UnicodeRange(0xA8D0, 0xA8D9, CharProperty.Numeric), + UnicodeRange(0xA8E0, 0xA8F1, CharProperty.Extend), + UnicodeRange(0xA8F2, 0xA8F7, CharProperty.ALetter), + UnicodeRange(0xA8FB, 0xA8FB, CharProperty.ALetter), + UnicodeRange(0xA8FD, 0xA8FE, CharProperty.ALetter), + UnicodeRange(0xA8FF, 0xA8FF, CharProperty.Extend), + UnicodeRange(0xA900, 0xA909, CharProperty.Numeric), + UnicodeRange(0xA90A, 0xA925, CharProperty.ALetter), + UnicodeRange(0xA926, 0xA92D, CharProperty.Extend), + UnicodeRange(0xA930, 0xA946, CharProperty.ALetter), + UnicodeRange(0xA947, 0xA953, CharProperty.Extend), + UnicodeRange(0xA960, 0xA97C, CharProperty.ALetter), + UnicodeRange(0xA980, 0xA983, CharProperty.Extend), + UnicodeRange(0xA984, 0xA9B2, CharProperty.ALetter), + UnicodeRange(0xA9B3, 0xA9C0, CharProperty.Extend), + UnicodeRange(0xA9CF, 0xA9CF, CharProperty.ALetter), + UnicodeRange(0xA9D0, 0xA9D9, CharProperty.Numeric), + UnicodeRange(0xA9E5, 0xA9E5, CharProperty.Extend), + UnicodeRange(0xA9F0, 0xA9F9, CharProperty.Numeric), + UnicodeRange(0xAA00, 0xAA28, CharProperty.ALetter), + UnicodeRange(0xAA29, 0xAA36, CharProperty.Extend), + UnicodeRange(0xAA40, 0xAA42, CharProperty.ALetter), + UnicodeRange(0xAA43, 0xAA43, CharProperty.Extend), + UnicodeRange(0xAA44, 0xAA4B, CharProperty.ALetter), + UnicodeRange(0xAA4C, 0xAA4D, CharProperty.Extend), + UnicodeRange(0xAA50, 0xAA59, CharProperty.Numeric), + UnicodeRange(0xAA7B, 0xAA7D, CharProperty.Extend), + UnicodeRange(0xAAB0, 0xAAB0, CharProperty.Extend), + UnicodeRange(0xAAB2, 0xAAB4, CharProperty.Extend), + UnicodeRange(0xAAB7, 0xAAB8, CharProperty.Extend), + UnicodeRange(0xAABE, 0xAABF, CharProperty.Extend), + UnicodeRange(0xAAC1, 0xAAC1, CharProperty.Extend), + UnicodeRange(0xAAE0, 0xAAEA, CharProperty.ALetter), + UnicodeRange(0xAAEB, 0xAAEF, CharProperty.Extend), + UnicodeRange(0xAAF2, 0xAAF4, CharProperty.ALetter), + UnicodeRange(0xAAF5, 0xAAF6, CharProperty.Extend), + UnicodeRange(0xAB01, 0xAB06, CharProperty.ALetter), + UnicodeRange(0xAB09, 0xAB0E, CharProperty.ALetter), + UnicodeRange(0xAB11, 0xAB16, CharProperty.ALetter), + UnicodeRange(0xAB20, 0xAB26, CharProperty.ALetter), + UnicodeRange(0xAB28, 0xAB2E, CharProperty.ALetter), + UnicodeRange(0xAB30, 0xAB65, CharProperty.ALetter), + UnicodeRange(0xAB70, 0xABE2, CharProperty.ALetter), + UnicodeRange(0xABE3, 0xABEA, CharProperty.Extend), + UnicodeRange(0xABEC, 0xABED, CharProperty.Extend), + UnicodeRange(0xABF0, 0xABF9, CharProperty.Numeric), + UnicodeRange(0xAC00, 0xD7A3, CharProperty.ALetter), + UnicodeRange(0xD7B0, 0xD7C6, CharProperty.ALetter), + UnicodeRange(0xD7CB, 0xD7FB, CharProperty.ALetter), + UnicodeRange(0xFB00, 0xFB06, CharProperty.ALetter), + UnicodeRange(0xFB13, 0xFB17, CharProperty.ALetter), + UnicodeRange(0xFB1D, 0xFB1D, CharProperty.HebrewLetter), + UnicodeRange(0xFB1E, 0xFB1E, CharProperty.Extend), + UnicodeRange(0xFB1F, 0xFB28, CharProperty.HebrewLetter), + UnicodeRange(0xFB2A, 0xFB36, CharProperty.HebrewLetter), + UnicodeRange(0xFB38, 0xFB3C, CharProperty.HebrewLetter), + UnicodeRange(0xFB3E, 0xFB3E, CharProperty.HebrewLetter), + UnicodeRange(0xFB40, 0xFB41, CharProperty.HebrewLetter), + UnicodeRange(0xFB43, 0xFB44, CharProperty.HebrewLetter), + UnicodeRange(0xFB46, 0xFB4F, CharProperty.HebrewLetter), + UnicodeRange(0xFB50, 0xFBB1, CharProperty.ALetter), + UnicodeRange(0xFBD3, 0xFD3D, CharProperty.ALetter), + UnicodeRange(0xFD50, 0xFD8F, CharProperty.ALetter), + UnicodeRange(0xFD92, 0xFDC7, CharProperty.ALetter), + UnicodeRange(0xFDF0, 0xFDFB, CharProperty.ALetter), + UnicodeRange(0xFE00, 0xFE0F, CharProperty.Extend), + UnicodeRange(0xFE10, 0xFE10, CharProperty.MidNum), + UnicodeRange(0xFE13, 0xFE13, CharProperty.MidLetter), + UnicodeRange(0xFE14, 0xFE14, CharProperty.MidNum), + UnicodeRange(0xFE20, 0xFE2F, CharProperty.Extend), + UnicodeRange(0xFE33, 0xFE34, CharProperty.ExtendNumLet), + UnicodeRange(0xFE4D, 0xFE4F, CharProperty.ExtendNumLet), + UnicodeRange(0xFE50, 0xFE50, CharProperty.MidNum), + UnicodeRange(0xFE52, 0xFE52, CharProperty.MidNumLet), + UnicodeRange(0xFE54, 0xFE54, CharProperty.MidNum), + UnicodeRange(0xFE55, 0xFE55, CharProperty.MidLetter), + UnicodeRange(0xFE70, 0xFE74, CharProperty.ALetter), + UnicodeRange(0xFE76, 0xFEFC, CharProperty.ALetter), + UnicodeRange(0xFEFF, 0xFEFF, CharProperty.Format), + UnicodeRange(0xFF07, 0xFF07, CharProperty.MidNumLet), + UnicodeRange(0xFF0C, 0xFF0C, CharProperty.MidNum), + UnicodeRange(0xFF0E, 0xFF0E, CharProperty.MidNumLet), + UnicodeRange(0xFF1A, 0xFF1A, CharProperty.MidLetter), + UnicodeRange(0xFF1B, 0xFF1B, CharProperty.MidNum), + UnicodeRange(0xFF21, 0xFF3A, CharProperty.ALetter), + UnicodeRange(0xFF3F, 0xFF3F, CharProperty.ExtendNumLet), + UnicodeRange(0xFF41, 0xFF5A, CharProperty.ALetter), + UnicodeRange(0xFF66, 0xFF9D, CharProperty.Katakana), + UnicodeRange(0xFF9E, 0xFF9F, CharProperty.Extend), + UnicodeRange(0xFFA0, 0xFFBE, CharProperty.ALetter), + UnicodeRange(0xFFC2, 0xFFC7, CharProperty.ALetter), + UnicodeRange(0xFFCA, 0xFFCF, CharProperty.ALetter), + UnicodeRange(0xFFD2, 0xFFD7, CharProperty.ALetter), + UnicodeRange(0xFFDA, 0xFFDC, CharProperty.ALetter), + UnicodeRange(0xFFF9, 0xFFFB, CharProperty.Format), + UnicodeRange(0x10000, 0x1000B, CharProperty.ALetter), + UnicodeRange(0x1000D, 0x10026, CharProperty.ALetter), + UnicodeRange(0x10028, 0x1003A, CharProperty.ALetter), + UnicodeRange(0x1003C, 0x1003D, CharProperty.ALetter), + UnicodeRange(0x1003F, 0x1004D, CharProperty.ALetter), + UnicodeRange(0x10050, 0x1005D, CharProperty.ALetter), + UnicodeRange(0x10080, 0x100FA, CharProperty.ALetter), + UnicodeRange(0x10140, 0x10174, CharProperty.ALetter), + UnicodeRange(0x101FD, 0x101FD, CharProperty.Extend), + UnicodeRange(0x10280, 0x1029C, CharProperty.ALetter), + UnicodeRange(0x102A0, 0x102D0, CharProperty.ALetter), + UnicodeRange(0x102E0, 0x102E0, CharProperty.Extend), + UnicodeRange(0x10300, 0x1031F, CharProperty.ALetter), + UnicodeRange(0x1032D, 0x1034A, CharProperty.ALetter), + UnicodeRange(0x10350, 0x10375, CharProperty.ALetter), + UnicodeRange(0x10376, 0x1037A, CharProperty.Extend), + UnicodeRange(0x10380, 0x1039D, CharProperty.ALetter), + UnicodeRange(0x103A0, 0x103C3, CharProperty.ALetter), + UnicodeRange(0x103C8, 0x103CF, CharProperty.ALetter), + UnicodeRange(0x103D1, 0x103D5, CharProperty.ALetter), + UnicodeRange(0x10400, 0x1049D, CharProperty.ALetter), + UnicodeRange(0x104A0, 0x104A9, CharProperty.Numeric), + UnicodeRange(0x104B0, 0x104D3, CharProperty.ALetter), + UnicodeRange(0x104D8, 0x104FB, CharProperty.ALetter), + UnicodeRange(0x10500, 0x10527, CharProperty.ALetter), + UnicodeRange(0x10530, 0x10563, CharProperty.ALetter), + UnicodeRange(0x10600, 0x10736, CharProperty.ALetter), + UnicodeRange(0x10740, 0x10755, CharProperty.ALetter), + UnicodeRange(0x10760, 0x10767, CharProperty.ALetter), + UnicodeRange(0x10800, 0x10805, CharProperty.ALetter), + UnicodeRange(0x10808, 0x10808, CharProperty.ALetter), + UnicodeRange(0x1080A, 0x10835, CharProperty.ALetter), + UnicodeRange(0x10837, 0x10838, CharProperty.ALetter), + UnicodeRange(0x1083C, 0x1083C, CharProperty.ALetter), + UnicodeRange(0x1083F, 0x10855, CharProperty.ALetter), + UnicodeRange(0x10860, 0x10876, CharProperty.ALetter), + UnicodeRange(0x10880, 0x1089E, CharProperty.ALetter), + UnicodeRange(0x108E0, 0x108F2, CharProperty.ALetter), + UnicodeRange(0x108F4, 0x108F5, CharProperty.ALetter), + UnicodeRange(0x10900, 0x10915, CharProperty.ALetter), + UnicodeRange(0x10920, 0x10939, CharProperty.ALetter), + UnicodeRange(0x10980, 0x109B7, CharProperty.ALetter), + UnicodeRange(0x109BE, 0x109BF, CharProperty.ALetter), + UnicodeRange(0x10A00, 0x10A00, CharProperty.ALetter), + UnicodeRange(0x10A01, 0x10A03, CharProperty.Extend), + UnicodeRange(0x10A05, 0x10A06, CharProperty.Extend), + UnicodeRange(0x10A0C, 0x10A0F, CharProperty.Extend), + UnicodeRange(0x10A10, 0x10A13, CharProperty.ALetter), + UnicodeRange(0x10A15, 0x10A17, CharProperty.ALetter), + UnicodeRange(0x10A19, 0x10A35, CharProperty.ALetter), + UnicodeRange(0x10A38, 0x10A3A, CharProperty.Extend), + UnicodeRange(0x10A3F, 0x10A3F, CharProperty.Extend), + UnicodeRange(0x10A60, 0x10A7C, CharProperty.ALetter), + UnicodeRange(0x10A80, 0x10A9C, CharProperty.ALetter), + UnicodeRange(0x10AC0, 0x10AC7, CharProperty.ALetter), + UnicodeRange(0x10AC9, 0x10AE4, CharProperty.ALetter), + UnicodeRange(0x10AE5, 0x10AE6, CharProperty.Extend), + UnicodeRange(0x10B00, 0x10B35, CharProperty.ALetter), + UnicodeRange(0x10B40, 0x10B55, CharProperty.ALetter), + UnicodeRange(0x10B60, 0x10B72, CharProperty.ALetter), + UnicodeRange(0x10B80, 0x10B91, CharProperty.ALetter), + UnicodeRange(0x10C00, 0x10C48, CharProperty.ALetter), + UnicodeRange(0x10C80, 0x10CB2, CharProperty.ALetter), + UnicodeRange(0x10CC0, 0x10CF2, CharProperty.ALetter), + UnicodeRange(0x10D00, 0x10D23, CharProperty.ALetter), + UnicodeRange(0x10D24, 0x10D27, CharProperty.Extend), + UnicodeRange(0x10D30, 0x10D39, CharProperty.Numeric), + UnicodeRange(0x10F00, 0x10F1C, CharProperty.ALetter), + UnicodeRange(0x10F27, 0x10F27, CharProperty.ALetter), + UnicodeRange(0x10F30, 0x10F45, CharProperty.ALetter), + UnicodeRange(0x10F46, 0x10F50, CharProperty.Extend), + UnicodeRange(0x11000, 0x11002, CharProperty.Extend), + UnicodeRange(0x11003, 0x11037, CharProperty.ALetter), + UnicodeRange(0x11038, 0x11046, CharProperty.Extend), + UnicodeRange(0x11066, 0x1106F, CharProperty.Numeric), + UnicodeRange(0x1107F, 0x11082, CharProperty.Extend), + UnicodeRange(0x11083, 0x110AF, CharProperty.ALetter), + UnicodeRange(0x110B0, 0x110BA, CharProperty.Extend), + UnicodeRange(0x110BD, 0x110BD, CharProperty.Format), + UnicodeRange(0x110CD, 0x110CD, CharProperty.Format), + UnicodeRange(0x110D0, 0x110E8, CharProperty.ALetter), + UnicodeRange(0x110F0, 0x110F9, CharProperty.Numeric), + UnicodeRange(0x11100, 0x11102, CharProperty.Extend), + UnicodeRange(0x11103, 0x11126, CharProperty.ALetter), + UnicodeRange(0x11127, 0x11134, CharProperty.Extend), + UnicodeRange(0x11136, 0x1113F, CharProperty.Numeric), + UnicodeRange(0x11144, 0x11144, CharProperty.ALetter), + UnicodeRange(0x11145, 0x11146, CharProperty.Extend), + UnicodeRange(0x11150, 0x11172, CharProperty.ALetter), + UnicodeRange(0x11173, 0x11173, CharProperty.Extend), + UnicodeRange(0x11176, 0x11176, CharProperty.ALetter), + UnicodeRange(0x11180, 0x11182, CharProperty.Extend), + UnicodeRange(0x11183, 0x111B2, CharProperty.ALetter), + UnicodeRange(0x111B3, 0x111C0, CharProperty.Extend), + UnicodeRange(0x111C1, 0x111C4, CharProperty.ALetter), + UnicodeRange(0x111C9, 0x111CC, CharProperty.Extend), + UnicodeRange(0x111D0, 0x111D9, CharProperty.Numeric), + UnicodeRange(0x111DA, 0x111DA, CharProperty.ALetter), + UnicodeRange(0x111DC, 0x111DC, CharProperty.ALetter), + UnicodeRange(0x11200, 0x11211, CharProperty.ALetter), + UnicodeRange(0x11213, 0x1122B, CharProperty.ALetter), + UnicodeRange(0x1122C, 0x11237, CharProperty.Extend), + UnicodeRange(0x1123E, 0x1123E, CharProperty.Extend), + UnicodeRange(0x11280, 0x11286, CharProperty.ALetter), + UnicodeRange(0x11288, 0x11288, CharProperty.ALetter), + UnicodeRange(0x1128A, 0x1128D, CharProperty.ALetter), + UnicodeRange(0x1128F, 0x1129D, CharProperty.ALetter), + UnicodeRange(0x1129F, 0x112A8, CharProperty.ALetter), + UnicodeRange(0x112B0, 0x112DE, CharProperty.ALetter), + UnicodeRange(0x112DF, 0x112EA, CharProperty.Extend), + UnicodeRange(0x112F0, 0x112F9, CharProperty.Numeric), + UnicodeRange(0x11300, 0x11303, CharProperty.Extend), + UnicodeRange(0x11305, 0x1130C, CharProperty.ALetter), + UnicodeRange(0x1130F, 0x11310, CharProperty.ALetter), + UnicodeRange(0x11313, 0x11328, CharProperty.ALetter), + UnicodeRange(0x1132A, 0x11330, CharProperty.ALetter), + UnicodeRange(0x11332, 0x11333, CharProperty.ALetter), + UnicodeRange(0x11335, 0x11339, CharProperty.ALetter), + UnicodeRange(0x1133B, 0x1133C, CharProperty.Extend), + UnicodeRange(0x1133D, 0x1133D, CharProperty.ALetter), + UnicodeRange(0x1133E, 0x11344, CharProperty.Extend), + UnicodeRange(0x11347, 0x11348, CharProperty.Extend), + UnicodeRange(0x1134B, 0x1134D, CharProperty.Extend), + UnicodeRange(0x11350, 0x11350, CharProperty.ALetter), + UnicodeRange(0x11357, 0x11357, CharProperty.Extend), + UnicodeRange(0x1135D, 0x11361, CharProperty.ALetter), + UnicodeRange(0x11362, 0x11363, CharProperty.Extend), + UnicodeRange(0x11366, 0x1136C, CharProperty.Extend), + UnicodeRange(0x11370, 0x11374, CharProperty.Extend), + UnicodeRange(0x11400, 0x11434, CharProperty.ALetter), + UnicodeRange(0x11435, 0x11446, CharProperty.Extend), + UnicodeRange(0x11447, 0x1144A, CharProperty.ALetter), + UnicodeRange(0x11450, 0x11459, CharProperty.Numeric), + UnicodeRange(0x1145E, 0x1145E, CharProperty.Extend), + UnicodeRange(0x11480, 0x114AF, CharProperty.ALetter), + UnicodeRange(0x114B0, 0x114C3, CharProperty.Extend), + UnicodeRange(0x114C4, 0x114C5, CharProperty.ALetter), + UnicodeRange(0x114C7, 0x114C7, CharProperty.ALetter), + UnicodeRange(0x114D0, 0x114D9, CharProperty.Numeric), + UnicodeRange(0x11580, 0x115AE, CharProperty.ALetter), + UnicodeRange(0x115AF, 0x115B5, CharProperty.Extend), + UnicodeRange(0x115B8, 0x115C0, CharProperty.Extend), + UnicodeRange(0x115D8, 0x115DB, CharProperty.ALetter), + UnicodeRange(0x115DC, 0x115DD, CharProperty.Extend), + UnicodeRange(0x11600, 0x1162F, CharProperty.ALetter), + UnicodeRange(0x11630, 0x11640, CharProperty.Extend), + UnicodeRange(0x11644, 0x11644, CharProperty.ALetter), + UnicodeRange(0x11650, 0x11659, CharProperty.Numeric), + UnicodeRange(0x11680, 0x116AA, CharProperty.ALetter), + UnicodeRange(0x116AB, 0x116B7, CharProperty.Extend), + UnicodeRange(0x116C0, 0x116C9, CharProperty.Numeric), + UnicodeRange(0x1171D, 0x1172B, CharProperty.Extend), + UnicodeRange(0x11730, 0x11739, CharProperty.Numeric), + UnicodeRange(0x11800, 0x1182B, CharProperty.ALetter), + UnicodeRange(0x1182C, 0x1183A, CharProperty.Extend), + UnicodeRange(0x118A0, 0x118DF, CharProperty.ALetter), + UnicodeRange(0x118E0, 0x118E9, CharProperty.Numeric), + UnicodeRange(0x118FF, 0x118FF, CharProperty.ALetter), + UnicodeRange(0x11A00, 0x11A00, CharProperty.ALetter), + UnicodeRange(0x11A01, 0x11A0A, CharProperty.Extend), + UnicodeRange(0x11A0B, 0x11A32, CharProperty.ALetter), + UnicodeRange(0x11A33, 0x11A39, CharProperty.Extend), + UnicodeRange(0x11A3A, 0x11A3A, CharProperty.ALetter), + UnicodeRange(0x11A3B, 0x11A3E, CharProperty.Extend), + UnicodeRange(0x11A47, 0x11A47, CharProperty.Extend), + UnicodeRange(0x11A50, 0x11A50, CharProperty.ALetter), + UnicodeRange(0x11A51, 0x11A5B, CharProperty.Extend), + UnicodeRange(0x11A5C, 0x11A83, CharProperty.ALetter), + UnicodeRange(0x11A86, 0x11A89, CharProperty.ALetter), + UnicodeRange(0x11A8A, 0x11A99, CharProperty.Extend), + UnicodeRange(0x11A9D, 0x11A9D, CharProperty.ALetter), + UnicodeRange(0x11AC0, 0x11AF8, CharProperty.ALetter), + UnicodeRange(0x11C00, 0x11C08, CharProperty.ALetter), + UnicodeRange(0x11C0A, 0x11C2E, CharProperty.ALetter), + UnicodeRange(0x11C2F, 0x11C36, CharProperty.Extend), + UnicodeRange(0x11C38, 0x11C3F, CharProperty.Extend), + UnicodeRange(0x11C40, 0x11C40, CharProperty.ALetter), + UnicodeRange(0x11C50, 0x11C59, CharProperty.Numeric), + UnicodeRange(0x11C72, 0x11C8F, CharProperty.ALetter), + UnicodeRange(0x11C92, 0x11CA7, CharProperty.Extend), + UnicodeRange(0x11CA9, 0x11CB6, CharProperty.Extend), + UnicodeRange(0x11D00, 0x11D06, CharProperty.ALetter), + UnicodeRange(0x11D08, 0x11D09, CharProperty.ALetter), + UnicodeRange(0x11D0B, 0x11D30, CharProperty.ALetter), + UnicodeRange(0x11D31, 0x11D36, CharProperty.Extend), + UnicodeRange(0x11D3A, 0x11D3A, CharProperty.Extend), + UnicodeRange(0x11D3C, 0x11D3D, CharProperty.Extend), + UnicodeRange(0x11D3F, 0x11D45, CharProperty.Extend), + UnicodeRange(0x11D46, 0x11D46, CharProperty.ALetter), + UnicodeRange(0x11D47, 0x11D47, CharProperty.Extend), + UnicodeRange(0x11D50, 0x11D59, CharProperty.Numeric), + UnicodeRange(0x11D60, 0x11D65, CharProperty.ALetter), + UnicodeRange(0x11D67, 0x11D68, CharProperty.ALetter), + UnicodeRange(0x11D6A, 0x11D89, CharProperty.ALetter), + UnicodeRange(0x11D8A, 0x11D8E, CharProperty.Extend), + UnicodeRange(0x11D90, 0x11D91, CharProperty.Extend), + UnicodeRange(0x11D93, 0x11D97, CharProperty.Extend), + UnicodeRange(0x11D98, 0x11D98, CharProperty.ALetter), + UnicodeRange(0x11DA0, 0x11DA9, CharProperty.Numeric), + UnicodeRange(0x11EE0, 0x11EF2, CharProperty.ALetter), + UnicodeRange(0x11EF3, 0x11EF6, CharProperty.Extend), + UnicodeRange(0x12000, 0x12399, CharProperty.ALetter), + UnicodeRange(0x12400, 0x1246E, CharProperty.ALetter), + UnicodeRange(0x12480, 0x12543, CharProperty.ALetter), + UnicodeRange(0x13000, 0x1342E, CharProperty.ALetter), + UnicodeRange(0x14400, 0x14646, CharProperty.ALetter), + UnicodeRange(0x16800, 0x16A38, CharProperty.ALetter), + UnicodeRange(0x16A40, 0x16A5E, CharProperty.ALetter), + UnicodeRange(0x16A60, 0x16A69, CharProperty.Numeric), + UnicodeRange(0x16AD0, 0x16AED, CharProperty.ALetter), + UnicodeRange(0x16AF0, 0x16AF4, CharProperty.Extend), + UnicodeRange(0x16B00, 0x16B2F, CharProperty.ALetter), + UnicodeRange(0x16B30, 0x16B36, CharProperty.Extend), + UnicodeRange(0x16B40, 0x16B43, CharProperty.ALetter), + UnicodeRange(0x16B50, 0x16B59, CharProperty.Numeric), + UnicodeRange(0x16B63, 0x16B77, CharProperty.ALetter), + UnicodeRange(0x16B7D, 0x16B8F, CharProperty.ALetter), + UnicodeRange(0x16E40, 0x16E7F, CharProperty.ALetter), + UnicodeRange(0x16F00, 0x16F44, CharProperty.ALetter), + UnicodeRange(0x16F50, 0x16F50, CharProperty.ALetter), + UnicodeRange(0x16F51, 0x16F7E, CharProperty.Extend), + UnicodeRange(0x16F8F, 0x16F92, CharProperty.Extend), + UnicodeRange(0x16F93, 0x16F9F, CharProperty.ALetter), + UnicodeRange(0x16FE0, 0x16FE1, CharProperty.ALetter), + UnicodeRange(0x1B000, 0x1B000, CharProperty.Katakana), + UnicodeRange(0x1BC00, 0x1BC6A, CharProperty.ALetter), + UnicodeRange(0x1BC70, 0x1BC7C, CharProperty.ALetter), + UnicodeRange(0x1BC80, 0x1BC88, CharProperty.ALetter), + UnicodeRange(0x1BC90, 0x1BC99, CharProperty.ALetter), + UnicodeRange(0x1BC9D, 0x1BC9E, CharProperty.Extend), + UnicodeRange(0x1BCA0, 0x1BCA3, CharProperty.Format), + UnicodeRange(0x1D165, 0x1D169, CharProperty.Extend), + UnicodeRange(0x1D16D, 0x1D172, CharProperty.Extend), + UnicodeRange(0x1D173, 0x1D17A, CharProperty.Format), + UnicodeRange(0x1D17B, 0x1D182, CharProperty.Extend), + UnicodeRange(0x1D185, 0x1D18B, CharProperty.Extend), + UnicodeRange(0x1D1AA, 0x1D1AD, CharProperty.Extend), + UnicodeRange(0x1D242, 0x1D244, CharProperty.Extend), + UnicodeRange(0x1D400, 0x1D454, CharProperty.ALetter), + UnicodeRange(0x1D456, 0x1D49C, CharProperty.ALetter), + UnicodeRange(0x1D49E, 0x1D49F, CharProperty.ALetter), + UnicodeRange(0x1D4A2, 0x1D4A2, CharProperty.ALetter), + UnicodeRange(0x1D4A5, 0x1D4A6, CharProperty.ALetter), + UnicodeRange(0x1D4A9, 0x1D4AC, CharProperty.ALetter), + UnicodeRange(0x1D4AE, 0x1D4B9, CharProperty.ALetter), + UnicodeRange(0x1D4BB, 0x1D4BB, CharProperty.ALetter), + UnicodeRange(0x1D4BD, 0x1D4C3, CharProperty.ALetter), + UnicodeRange(0x1D4C5, 0x1D505, CharProperty.ALetter), + UnicodeRange(0x1D507, 0x1D50A, CharProperty.ALetter), + UnicodeRange(0x1D50D, 0x1D514, CharProperty.ALetter), + UnicodeRange(0x1D516, 0x1D51C, CharProperty.ALetter), + UnicodeRange(0x1D51E, 0x1D539, CharProperty.ALetter), + UnicodeRange(0x1D53B, 0x1D53E, CharProperty.ALetter), + UnicodeRange(0x1D540, 0x1D544, CharProperty.ALetter), + UnicodeRange(0x1D546, 0x1D546, CharProperty.ALetter), + UnicodeRange(0x1D54A, 0x1D550, CharProperty.ALetter), + UnicodeRange(0x1D552, 0x1D6A5, CharProperty.ALetter), + UnicodeRange(0x1D6A8, 0x1D6C0, CharProperty.ALetter), + UnicodeRange(0x1D6C2, 0x1D6DA, CharProperty.ALetter), + UnicodeRange(0x1D6DC, 0x1D6FA, CharProperty.ALetter), + UnicodeRange(0x1D6FC, 0x1D714, CharProperty.ALetter), + UnicodeRange(0x1D716, 0x1D734, CharProperty.ALetter), + UnicodeRange(0x1D736, 0x1D74E, CharProperty.ALetter), + UnicodeRange(0x1D750, 0x1D76E, CharProperty.ALetter), + UnicodeRange(0x1D770, 0x1D788, CharProperty.ALetter), + UnicodeRange(0x1D78A, 0x1D7A8, CharProperty.ALetter), + UnicodeRange(0x1D7AA, 0x1D7C2, CharProperty.ALetter), + UnicodeRange(0x1D7C4, 0x1D7CB, CharProperty.ALetter), + UnicodeRange(0x1D7CE, 0x1D7FF, CharProperty.Numeric), + UnicodeRange(0x1DA00, 0x1DA36, CharProperty.Extend), + UnicodeRange(0x1DA3B, 0x1DA6C, CharProperty.Extend), + UnicodeRange(0x1DA75, 0x1DA75, CharProperty.Extend), + UnicodeRange(0x1DA84, 0x1DA84, CharProperty.Extend), + UnicodeRange(0x1DA9B, 0x1DA9F, CharProperty.Extend), + UnicodeRange(0x1DAA1, 0x1DAAF, CharProperty.Extend), + UnicodeRange(0x1E000, 0x1E006, CharProperty.Extend), + UnicodeRange(0x1E008, 0x1E018, CharProperty.Extend), + UnicodeRange(0x1E01B, 0x1E021, CharProperty.Extend), + UnicodeRange(0x1E023, 0x1E024, CharProperty.Extend), + UnicodeRange(0x1E026, 0x1E02A, CharProperty.Extend), + UnicodeRange(0x1E800, 0x1E8C4, CharProperty.ALetter), + UnicodeRange(0x1E8D0, 0x1E8D6, CharProperty.Extend), + UnicodeRange(0x1E900, 0x1E943, CharProperty.ALetter), + UnicodeRange(0x1E944, 0x1E94A, CharProperty.Extend), + UnicodeRange(0x1E950, 0x1E959, CharProperty.Numeric), + UnicodeRange(0x1EE00, 0x1EE03, CharProperty.ALetter), + UnicodeRange(0x1EE05, 0x1EE1F, CharProperty.ALetter), + UnicodeRange(0x1EE21, 0x1EE22, CharProperty.ALetter), + UnicodeRange(0x1EE24, 0x1EE24, CharProperty.ALetter), + UnicodeRange(0x1EE27, 0x1EE27, CharProperty.ALetter), + UnicodeRange(0x1EE29, 0x1EE32, CharProperty.ALetter), + UnicodeRange(0x1EE34, 0x1EE37, CharProperty.ALetter), + UnicodeRange(0x1EE39, 0x1EE39, CharProperty.ALetter), + UnicodeRange(0x1EE3B, 0x1EE3B, CharProperty.ALetter), + UnicodeRange(0x1EE42, 0x1EE42, CharProperty.ALetter), + UnicodeRange(0x1EE47, 0x1EE47, CharProperty.ALetter), + UnicodeRange(0x1EE49, 0x1EE49, CharProperty.ALetter), + UnicodeRange(0x1EE4B, 0x1EE4B, CharProperty.ALetter), + UnicodeRange(0x1EE4D, 0x1EE4F, CharProperty.ALetter), + UnicodeRange(0x1EE51, 0x1EE52, CharProperty.ALetter), + UnicodeRange(0x1EE54, 0x1EE54, CharProperty.ALetter), + UnicodeRange(0x1EE57, 0x1EE57, CharProperty.ALetter), + UnicodeRange(0x1EE59, 0x1EE59, CharProperty.ALetter), + UnicodeRange(0x1EE5B, 0x1EE5B, CharProperty.ALetter), + UnicodeRange(0x1EE5D, 0x1EE5D, CharProperty.ALetter), + UnicodeRange(0x1EE5F, 0x1EE5F, CharProperty.ALetter), + UnicodeRange(0x1EE61, 0x1EE62, CharProperty.ALetter), + UnicodeRange(0x1EE64, 0x1EE64, CharProperty.ALetter), + UnicodeRange(0x1EE67, 0x1EE6A, CharProperty.ALetter), + UnicodeRange(0x1EE6C, 0x1EE72, CharProperty.ALetter), + UnicodeRange(0x1EE74, 0x1EE77, CharProperty.ALetter), + UnicodeRange(0x1EE79, 0x1EE7C, CharProperty.ALetter), + UnicodeRange(0x1EE7E, 0x1EE7E, CharProperty.ALetter), + UnicodeRange(0x1EE80, 0x1EE89, CharProperty.ALetter), + UnicodeRange(0x1EE8B, 0x1EE9B, CharProperty.ALetter), + UnicodeRange(0x1EEA1, 0x1EEA3, CharProperty.ALetter), + UnicodeRange(0x1EEA5, 0x1EEA9, CharProperty.ALetter), + UnicodeRange(0x1EEAB, 0x1EEBB, CharProperty.ALetter), + UnicodeRange(0x1F130, 0x1F149, CharProperty.ALetter), + UnicodeRange(0x1F150, 0x1F169, CharProperty.ALetter), + UnicodeRange(0x1F170, 0x1F189, CharProperty.ALetter), + UnicodeRange(0x1F1E6, 0x1F1FF, CharProperty.RegionalIndicator), + UnicodeRange(0x1F3FB, 0x1F3FF, CharProperty.Extend), + UnicodeRange(0xE0001, 0xE0001, CharProperty.Format), + UnicodeRange(0xE0020, 0xE007F, CharProperty.Extend), + UnicodeRange(0xE0100, 0xE01EF, CharProperty.Extend) +]); diff --git a/lib/stub_ui/lib/src/engine/text/word_breaker.dart b/lib/stub_ui/lib/src/engine/text/word_breaker.dart new file mode 100644 index 0000000000000..d0865c399e5dd --- /dev/null +++ b/lib/stub_ui/lib/src/engine/text/word_breaker.dart @@ -0,0 +1,308 @@ +// 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. + +part of engine; + +enum _FindBreakDirection { + /// Indicates to find the word break by looking forward. + forward, + + /// Indicates to find the word break by looking backward. + backward, +} + +/// [WordBreaker] exposes static methods to identify word boundaries. +abstract class WordBreaker { + /// It starts from [index] and tries to find the next word boundary in [text]. + static int nextBreakIndex(String text, int index) => + _findBreakIndex(_FindBreakDirection.forward, text, index); + + /// It starts from [index] and tries to find the previous word boundary in + /// [text]. + static int prevBreakIndex(String text, int index) => + _findBreakIndex(_FindBreakDirection.backward, text, index); + + static int _findBreakIndex( + _FindBreakDirection direction, + String text, + int index, + ) { + int step, min, max; + if (direction == _FindBreakDirection.forward) { + step = 1; + min = 0; + max = text.length - 1; + } else { + step = -1; + min = 1; + max = text.length; + } + + int i = index; + while (i >= min && i <= max) { + i += step; + if (_isBreak(text, i)) { + break; + } + } + return i; + } + + /// Find out if there's a word break between [index - 1] and [index]. + /// http://unicode.org/reports/tr29/#Word_Boundary_Rules + static bool _isBreak(String text, int index) { + // Break at the start and end of text. + // WB1: sot ÷ Any + // WB2: Any ÷ eot + if (index <= 0 || index >= text.length) { + return true; + } + + // Do not break inside surrogate pair + if (_isUtf16Surrogate(text.codeUnitAt(index - 1))) { + return false; + } + + CharProperty immediateRight = getCharProperty(text, index); + CharProperty immediateLeft = getCharProperty(text, index - 1); + + // Do not break within CRLF. + // WB3: CR × LF + if (immediateLeft == CharProperty.CR && immediateRight == CharProperty.LF) + return false; + + // Otherwise break before and after Newlines (including CR and LF) + // WB3a: (Newline | CR | LF) ÷ + if (_oneOf( + immediateLeft, + CharProperty.Newline, + CharProperty.CR, + CharProperty.LF, + )) return true; + + // WB3b: ÷ (Newline | CR | LF) + if (_oneOf( + immediateRight, + CharProperty.Newline, + CharProperty.CR, + CharProperty.LF, + )) return true; + + // WB3c: ZWJ × \p{Extended_Pictographic} + // TODO(flutter_web): What's the right way to implement this? + + // Keep horizontal whitespace together. + // WB3d: WSegSpace × WSegSpace + if (immediateLeft == CharProperty.WSegSpace && + immediateRight == CharProperty.WSegSpace) return false; + + // Ignore Format and Extend characters, except after sot, CR, LF, and + // Newline. + // WB4: X (Extend | Format | ZWJ)* → X + if (_oneOf( + immediateRight, + CharProperty.Extend, + CharProperty.Format, + CharProperty.ZWJ, + )) { + // The Extend|Format|ZWJ character is to the right, so it is attached + // to a character to the left, don't split here + return false; + } + + // We've reached the end of an Extend|Format|ZWJ sequence, collapse it. + int l = 0; + while (_oneOf( + immediateLeft, + CharProperty.Extend, + CharProperty.Format, + CharProperty.ZWJ, + )) { + l++; + if (index - l - 1 < 0) { + // Reached the beginning of text. + return true; + } + immediateLeft = getCharProperty(text, index - l - 1); + } + + // Do not break between most letters. + // WB5: (ALetter | Hebrew_Letter) × (ALetter | Hebrew_Letter) + if (_isAHLetter(immediateLeft) && _isAHLetter(immediateRight)) return false; + + // Some tests beyond this point require more context. We need to get that + // context while also respecting rule WB4. So ignore Format, Extend and ZWJ. + + // Skip all Format, Extend and ZWJ to the right. + int r = 0; + CharProperty nextRight; + do { + r++; + nextRight = getCharProperty(text, index + r); + } while (_oneOf( + nextRight, + CharProperty.Extend, + CharProperty.Format, + CharProperty.ZWJ, + )); + + // Skip all Format, Extend and ZWJ to the left. + CharProperty nextLeft; + do { + l++; + nextLeft = getCharProperty(text, index - l - 1); + } while (_oneOf( + nextLeft, + CharProperty.Extend, + CharProperty.Format, + CharProperty.ZWJ, + )); + + // Do not break letters across certain punctuation. + // WB6: (AHLetter) × (MidLetter | MidNumLet | Single_Quote) (AHLetter) + if (_isAHLetter(immediateLeft) && + _oneOf( + immediateRight, + CharProperty.MidLetter, + CharProperty.MidNumLet, + CharProperty.SingleQuote, + ) && + _isAHLetter(nextRight)) { + return false; + } + + // WB7: (AHLetter) (MidLetter | MidNumLet | Single_Quote) × (AHLetter) + if (_isAHLetter(nextLeft) && + _oneOf( + immediateLeft, + CharProperty.MidLetter, + CharProperty.MidNumLet, + CharProperty.SingleQuote, + ) && + _isAHLetter(immediateRight)) { + return false; + } + + // WB7a: Hebrew_Letter × Single_Quote + if (immediateLeft == CharProperty.HebrewLetter && + immediateRight == CharProperty.SingleQuote) return false; + + // WB7b: Hebrew_Letter × Double_Quote Hebrew_Letter + if (immediateLeft == CharProperty.HebrewLetter && + immediateRight == CharProperty.DoubleQuote && + nextRight == CharProperty.HebrewLetter) return false; + + // WB7c: Hebrew_Letter Double_Quote × Hebrew_Letter + if (nextLeft == CharProperty.HebrewLetter && + immediateLeft == CharProperty.DoubleQuote && + immediateRight == CharProperty.HebrewLetter) return false; + + // Do not break within sequences of digits, or digits adjacent to letters + // (“3a”, or “A3”). + // WB8: Numeric × Numeric + if (immediateLeft == CharProperty.Numeric && + immediateRight == CharProperty.Numeric) return false; + + // WB9: AHLetter × Numeric + if (_isAHLetter(immediateLeft) && immediateRight == CharProperty.Numeric) + return false; + + // WB10: Numeric × AHLetter + if (immediateLeft == CharProperty.Numeric && _isAHLetter(immediateRight)) + return false; + + // Do not break within sequences, such as “3.2” or “3,456.789”. + // WB11: Numeric (MidNum | MidNumLet | Single_Quote) × Numeric + if (nextLeft == CharProperty.Numeric && + _oneOf( + immediateLeft, + CharProperty.MidNum, + CharProperty.MidNumLet, + CharProperty.SingleQuote, + ) && + immediateRight == CharProperty.Numeric) { + return false; + } + + // WB12: Numeric × (MidNum | MidNumLet | Single_Quote) Numeric + if (immediateLeft == CharProperty.Numeric && + _oneOf( + immediateRight, + CharProperty.MidNum, + CharProperty.MidNumLet, + CharProperty.SingleQuote, + ) && + nextRight == CharProperty.Numeric) { + return false; + } + + // Do not break between Katakana. + // WB13: Katakana × Katakana + if (immediateLeft == CharProperty.Katakana && + immediateRight == CharProperty.Katakana) return false; + + // Do not break from extenders. + // WB13a: (AHLetter | Numeric | Katakana | ExtendNumLet) × ExtendNumLet + if (_oneOf( + immediateLeft, + CharProperty.ALetter, + CharProperty.HebrewLetter, + CharProperty.Numeric, + CharProperty.Katakana, + CharProperty.ExtendNumLet, + ) && + immediateRight == CharProperty.ExtendNumLet) { + return false; + } + + // WB13b: ExtendNumLet × (AHLetter | Numeric | Katakana) + if (immediateLeft == CharProperty.ExtendNumLet && + _oneOf( + immediateRight, + CharProperty.ALetter, + CharProperty.HebrewLetter, + CharProperty.Numeric, + CharProperty.Katakana, + )) { + return false; + } + + // Do not break within emoji flag sequences. That is, do not break between + // regional indicator (RI) symbols if there is an odd number of RI + // characters before the break point. + // WB15: sot (RI RI)* RI × RI + // TODO(mdebbar): implement this. + + // WB16: [^RI] (RI RI)* RI × RI + // TODO(mdebbar): implement this. + + // Otherwise, break everywhere (including around ideographs). + // WB999: Any ÷ Any + return true; + } + + static bool _isUtf16Surrogate(int value) { + return value & 0xF800 == 0xD800; + } + + static bool _oneOf( + CharProperty value, + CharProperty choice1, + CharProperty choice2, [ + CharProperty choice3, + CharProperty choice4, + CharProperty choice5, + ]) { + if (value == choice1) return true; + if (value == choice2) return true; + if (choice3 != null && value == choice3) return true; + if (choice4 != null && value == choice4) return true; + if (choice5 != null && value == choice5) return true; + return false; + } + + static bool _isAHLetter(CharProperty property) { + return _oneOf(property, CharProperty.ALetter, CharProperty.HebrewLetter); + } +} diff --git a/lib/stub_ui/lib/src/engine/text_editing.dart b/lib/stub_ui/lib/src/engine/text_editing.dart new file mode 100644 index 0000000000000..53f6719ffb86f --- /dev/null +++ b/lib/stub_ui/lib/src/engine/text_editing.dart @@ -0,0 +1,616 @@ +// 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. + +part of engine; + +/// Make the content editable span visible to facilitate debugging. +const _debugVisibleTextEditing = false; + +void _emptyCallback(_) {} + +void _styleEditingElement(html.HtmlElement domElement) { + domElement.style + ..position = 'fixed' + ..whiteSpace = 'pre'; + if (_debugVisibleTextEditing) { + domElement.style + ..bottom = '0' + ..right = '0' + ..font = '24px sans-serif' + ..color = 'purple' + ..backgroundColor = 'pink'; + } else { + domElement.style + ..overflow = 'hidden' + ..transform = 'translate(-99999px, -99999px)' + // width and height can't be zero because then the element would stop + // receiving edits when its content is empty. + ..width = '1px' + ..height = '1px'; + } + if (browserEngine == BrowserEngine.webkit) { + // TODO(flutter_web): Remove once webkit issue of paragraphs incorrectly + // rendering (shifting up) is resolved. Temporarily force relayout + // a frame after input is created. + html.window.animationFrame.then((num _) { + domElement.style + ..position = 'absolute' + ..bottom = '0' + ..right = '0'; + }); + } +} + +html.InputElement _createInputElement() { + final html.InputElement input = html.InputElement(); + _styleEditingElement(input); + return input; +} + +html.TextAreaElement _createTextAreaElement() { + final html.TextAreaElement textarea = html.TextAreaElement(); + _styleEditingElement(textarea); + return textarea; +} + +/// The current text and selection state of a text field. +class EditingState { + EditingState({this.text, this.baseOffset = 0, this.extentOffset = 0}); + + /// Creates an [EditingState] instance using values from an editing state Map + /// coming from Flutter. + /// + /// The `editingState` Map has the following structure: + /// ```json + /// { + /// "text": "The text here", + /// "selectionBase": 0, + /// "selectionExtent": 0, + /// "selectionAffinity": "TextAffinity.upstream", + /// "selectionIsDirectional": false, + /// "composingBase": -1, + /// "composingExtent": -1 + /// } + /// ``` + EditingState.fromFlutter(Map flutterEditingState) + : text = flutterEditingState['text'], + baseOffset = flutterEditingState['selectionBase'], + extentOffset = flutterEditingState['selectionExtent']; + + /// The counterpart of [EditingState.fromFlutter]. It generates a Map that + /// can be sent to Flutter. + // TODO(mdebbar): Should we get `selectionAffinity` and other properties from flutter's editing state? + Map toFlutter() => { + 'text': text, + 'selectionBase': baseOffset, + 'selectionExtent': extentOffset, + }; + + /// The current text being edited. + final String text; + + /// The offset at which the text selection originates. + final int baseOffset; + + /// The offset at which the text selection terminates. + final int extentOffset; + + /// Whether the current editing state is valid or not. + bool get isValid => baseOffset >= 0 && extentOffset >= 0; + + @override + bool operator ==(dynamic other) { + if (identical(this, other)) return true; + if (runtimeType != other.runtimeType) return false; + final EditingState typedOther = other; + return text == typedOther.text && + baseOffset == typedOther.baseOffset && + extentOffset == typedOther.extentOffset; + } + + @override + String toString() { + return assertionsEnabled + ? 'EditingState("$text", base:$baseOffset, extent:$extentOffset)' + : super.toString(); + } +} + +/// Various types of inputs used in text fields. +/// +/// These types are coming from Flutter's [TextInputType]. Currently, we don't +/// support all the types. We fallback to [InputType.text] when Flutter sends +/// a type that isn't supported. +// TODO(flutter_web): Support more types. +enum InputType { + /// Single-line plain text. + text, + + /// Multi-line text. + multiline, +} + +InputType _getInputTypeFromString(String inputType) { + switch (inputType) { + case 'TextInputType.multiline': + return InputType.multiline; + + case 'TextInputType.text': + default: + return InputType.text; + } +} + +/// Controls the appearance of the input control being edited. +/// +/// For example, [inputType] determines whether we should use `` or +/// `