├── macos
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Runner
│ ├── Configs
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ ├── Warnings.xcconfig
│ │ └── AppInfo.xcconfig
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── app_icon_16.png
│ │ │ ├── app_icon_32.png
│ │ │ ├── app_icon_64.png
│ │ │ ├── app_icon_1024.png
│ │ │ ├── app_icon_128.png
│ │ │ ├── app_icon_256.png
│ │ │ ├── app_icon_512.png
│ │ │ └── Contents.json
│ ├── Release.entitlements
│ ├── AppDelegate.swift
│ ├── DebugProfile.entitlements
│ ├── MainFlutterWindow.swift
│ ├── Info.plist
│ └── Base.lproj
│ │ └── MainMenu.xib
├── .gitignore
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ └── project.pbxproj
└── RunnerTests
│ └── RunnerTests.swift
├── shaders
├── colors.frag
├── flutter_gpu_unlit.frag
├── colors.vert
├── flutter_gpu_texture.frag
├── flutter_gpu_unlit.vert
├── flutter_gpu_texture.vert
└── TestLibrary.shaderbundle.json
├── hook
└── build.dart
├── README.md
├── lib
├── shaders.dart
├── main.dart
├── colors.dart
├── julia.dart
├── triangle.dart
└── texture_cube.dart
├── .gitignore
├── run.sh
├── analysis_options.yaml
├── .metadata
├── pubspec.yaml
└── pubspec.lock
/macos/Flutter/Flutter-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "ephemeral/Flutter-Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/macos/Flutter/Flutter-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "ephemeral/Flutter-Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Debug.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Release.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/.gitignore:
--------------------------------------------------------------------------------
1 | # Flutter-related
2 | **/Flutter/ephemeral/
3 | **/Pods/
4 |
5 | # Xcode-related
6 | **/dgph
7 | **/xcuserdata/
8 |
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bdero/flutter-gpu-examples/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bdero/flutter-gpu-examples/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bdero/flutter-gpu-examples/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bdero/flutter-gpu-examples/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bdero/flutter-gpu-examples/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bdero/flutter-gpu-examples/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bdero/flutter-gpu-examples/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/macos/Flutter/GeneratedPluginRegistrant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | import FlutterMacOS
6 | import Foundation
7 |
8 |
9 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
10 | }
11 |
--------------------------------------------------------------------------------
/macos/Runner/Release.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/shaders/colors.frag:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | in vec4 v_color;
6 | out vec4 frag_color;
7 |
8 | void main() {
9 | frag_color = v_color;
10 | }
11 |
--------------------------------------------------------------------------------
/shaders/flutter_gpu_unlit.frag:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | in vec4 v_color;
6 | out vec4 frag_color;
7 |
8 | void main() {
9 | frag_color = v_color;
10 | }
11 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import FlutterMacOS
2 | import Cocoa
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/macos/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | @main
5 | class AppDelegate: FlutterAppDelegate {
6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7 | return true
8 | }
9 |
10 | override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
11 | return true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/shaders/colors.vert:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | #version 320 es
6 |
7 | in vec2 position;
8 | in vec4 color;
9 |
10 | out vec4 v_color;
11 |
12 | void main() {
13 | v_color = color;
14 | gl_Position = vec4(position, 0.0, 1.0);
15 | }
16 |
--------------------------------------------------------------------------------
/hook/build.dart:
--------------------------------------------------------------------------------
1 | import 'package:native_assets_cli/native_assets_cli.dart';
2 | import 'package:flutter_gpu_shaders/build.dart';
3 |
4 | void main(List args) async {
5 | await build(args, (config, output) async {
6 | await buildShaderBundleJson(
7 | buildConfig: config,
8 | buildOutput: output,
9 | manifestFileName: 'shaders/TestLibrary.shaderbundle.json');
10 | });
11 | }
--------------------------------------------------------------------------------
/shaders/flutter_gpu_texture.frag:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | uniform sampler2D tex;
6 |
7 | in vec2 v_texture_coords;
8 | in vec4 v_color;
9 | out vec4 frag_color;
10 |
11 | void main() {
12 | frag_color = v_color * texture(tex, v_texture_coords);
13 | }
14 |
--------------------------------------------------------------------------------
/macos/Runner/DebugProfile.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 | com.apple.security.network.server
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/shaders/flutter_gpu_unlit.vert:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 | uniform FrameInfo {
5 | mat4 mvp;
6 | vec4 color;
7 | }
8 | frame_info;
9 |
10 | in vec2 position;
11 | out vec4 v_color;
12 |
13 | void main() {
14 | v_color = frame_info.color;
15 | gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
16 | }
17 |
--------------------------------------------------------------------------------
/macos/Runner/MainFlutterWindow.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | class MainFlutterWindow: NSWindow {
5 | override func awakeFromNib() {
6 | let flutterViewController = FlutterViewController()
7 | let windowFrame = self.frame
8 | self.contentViewController = flutterViewController
9 | self.setFrame(windowFrame, display: true)
10 |
11 | RegisterGeneratedPlugins(registry: flutterViewController)
12 |
13 | super.awakeFromNib()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flutter GPU examples
2 |
3 | Currently only supports MacOS.
4 |
5 | ## Build instructions
6 |
7 | 1. Follow the instructions in the [Flutter GPU documentation](https://github.com/flutter/flutter/blob/master/docs/engine/impeller/Flutter-GPU.md) to properly set up your Flutter checkout.
8 | 2. Edit the `flutter_gpu` path in `pubspec.yaml` to match your local engine checkout.
9 | 3. Edit the `IMPELLERC` and `ENGINE_DIR` paths in `run.sh`.
10 | 4. Run `run.sh` to install dependencies and build shaders.
11 | 5. `flutter run -d macos`
12 |
--------------------------------------------------------------------------------
/shaders/flutter_gpu_texture.vert:
--------------------------------------------------------------------------------
1 | // Copyright 2013 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 | uniform FrameInfo {
5 | mat4 mvp;
6 | }
7 | frame_info;
8 |
9 | in vec3 position;
10 | in vec2 texture_coords;
11 | in vec4 color;
12 | out vec2 v_texture_coords;
13 | out vec4 v_color;
14 |
15 | void main() {
16 | v_texture_coords = texture_coords;
17 | v_color = color;
18 | gl_Position = frame_info.mvp * vec4(position, 1.0);
19 | }
20 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2 | GCC_WARN_UNDECLARED_SELECTOR = YES
3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6 | CLANG_WARN_PRAGMA_PACK = YES
7 | CLANG_WARN_STRICT_PROTOTYPES = YES
8 | CLANG_WARN_COMMA = YES
9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES
10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12 | GCC_WARN_SHADOW = YES
13 | CLANG_WARN_UNREACHABLE_CODE = YES
14 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/AppInfo.xcconfig:
--------------------------------------------------------------------------------
1 | // Application-level settings for the Runner target.
2 | //
3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4 | // future. If not, the values below would default to using the project name when this becomes a
5 | // 'flutter create' template.
6 |
7 | // The application's name. By default this is also the title of the Flutter window.
8 | PRODUCT_NAME = gputest
9 |
10 | // The application's bundle identifier
11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.gputest
12 |
13 | // The copyright displayed in application information
14 | PRODUCT_COPYRIGHT = Copyright © 2023 com.example. All rights reserved.
15 |
--------------------------------------------------------------------------------
/lib/shaders.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_gpu/gpu.dart' as gpu;
2 |
3 | const String _kShaderBundlePath =
4 | 'build/shaderbundles/TestLibrary.shaderbundle';
5 | // NOTE: If you're building a library, the path must be prefixed
6 | // with a package name. For example:
7 | // 'packages/my_cool_renderer/build/shaderbundles/my_renderer.shaderbundle'
8 |
9 | gpu.ShaderLibrary? _shaderLibrary;
10 | gpu.ShaderLibrary get shaderLibrary {
11 | if (_shaderLibrary != null) {
12 | return _shaderLibrary!;
13 | }
14 | _shaderLibrary = gpu.ShaderLibrary.fromAsset(_kShaderBundlePath);
15 | if (_shaderLibrary != null) {
16 | return _shaderLibrary!;
17 | }
18 |
19 | throw Exception("Failed to load shader bundle! ($_kShaderBundlePath)");
20 | }
--------------------------------------------------------------------------------
/shaders/TestLibrary.shaderbundle.json:
--------------------------------------------------------------------------------
1 | {
2 | "ColorsVertex": {
3 | "type": "vertex",
4 | "file": "shaders/colors.vert"
5 | },
6 | "ColorsFragment": {
7 | "type": "fragment",
8 | "file": "shaders/colors.frag"
9 | },
10 | "TextureVertex": {
11 | "type": "vertex",
12 | "file": "shaders/flutter_gpu_texture.vert"
13 | },
14 | "TextureFragment": {
15 | "type": "fragment",
16 | "file": "shaders/flutter_gpu_texture.frag"
17 | },
18 | "UnlitVertex": {
19 | "type": "vertex",
20 | "file": "shaders/flutter_gpu_unlit.vert"
21 | },
22 | "UnlitFragment": {
23 | "type": "fragment",
24 | "file": "shaders/flutter_gpu_unlit.frag"
25 | }
26 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .build/
9 | .buildlog/
10 | .history
11 | .svn/
12 | .swiftpm/
13 | migrate_working_dir/
14 |
15 | # IntelliJ related
16 | *.iml
17 | *.ipr
18 | *.iws
19 | .idea/
20 |
21 | # The .vscode folder contains launch configuration and tasks you configure in
22 | # VS Code which you may wish to be included in version control, so this line
23 | # is commented out by default.
24 | #.vscode/
25 |
26 | # Flutter/Dart/Pub related
27 | **/doc/api/
28 | **/ios/Flutter/.last_build_id
29 | .dart_tool/
30 | .flutter-plugins
31 | .flutter-plugins-dependencies
32 | .packages
33 | .pub-cache/
34 | .pub/
35 | /build/
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
48 | **/*.shaderbundle
49 |
--------------------------------------------------------------------------------
/macos/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | $(PRODUCT_COPYRIGHT)
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 | FLTEnableImpeller
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | set -ex
2 |
3 | SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
4 | ENGINE_DIR=~/projects/flutter/engine/src
5 | IMPELLERC=$ENGINE_DIR/out/host_debug_unopt_arm64/impellerc
6 |
7 | mkdir -p $SCRIPT_DIR/assets
8 | $IMPELLERC \
9 | --include=$ENGINE_DIR/flutter/impeller/compiler/shader_lib \
10 | --runtime-stage-metal \
11 | --sl=assets/TestLibrary.shaderbundle \
12 | --shader-bundle=\{\
13 | \"UnlitFragment\":\ \{\"type\":\ \"fragment\",\ \"file\":\ \"$SCRIPT_DIR/shaders/flutter_gpu_unlit.frag\"\},\ \
14 | \"UnlitVertex\":\ \{\"type\":\ \"vertex\",\ \"file\":\ \"$SCRIPT_DIR/shaders/flutter_gpu_unlit.vert\"\},\ \
15 | \"TextureFragment\":\ \{\"type\":\ \"fragment\",\ \"file\":\ \"$SCRIPT_DIR/shaders/flutter_gpu_texture.frag\"\},\ \
16 | \"TextureVertex\":\ \{\"type\":\ \"vertex\",\ \"file\":\ \"$SCRIPT_DIR/shaders/flutter_gpu_texture.vert\"\},\ \
17 | \"ColorsFragment\":\ \{\"type\":\ \"fragment\",\ \"file\":\ \"$SCRIPT_DIR/shaders/colors.frag\"\},\ \
18 | \"ColorsVertex\":\ \{\"type\":\ \"vertex\",\ \"file\":\ \"$SCRIPT_DIR/shaders/colors.vert\"\}\}
19 |
20 | select opt in macos quit; do
21 | case $opt in
22 | macos)
23 | flutter run \
24 | --debug \
25 | --local-engine-src-path $ENGINE_DIR \
26 | --local-engine=host_debug_unopt_arm64 \
27 | --local-engine-host=host_debug_unopt_arm64 \
28 | -d macos \
29 | --enable-impeller
30 | ;;
31 | quit)
32 | break
33 | ;;
34 | *)
35 | echo "Invalid option $REPLY"
36 | ;;
37 | esac
38 | done
39 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "app_icon_16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "app_icon_32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "app_icon_32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "app_icon_64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "app_icon_128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "app_icon_256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "app_icon_256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "app_icon_512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "app_icon_512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "app_icon_1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled.
5 |
6 | version:
7 | revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
8 | channel: unknown
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
17 | base_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
18 | - platform: android
19 | create_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
20 | base_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
21 | - platform: ios
22 | create_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
23 | base_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
24 | - platform: linux
25 | create_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
26 | base_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
27 | - platform: macos
28 | create_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
29 | base_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
30 | - platform: web
31 | create_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
32 | base_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
33 | - platform: windows
34 | create_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
35 | base_revision: 55c988fb453eddd97cb2e4d6df9ec28d72e2e899
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:gputest/colors.dart';
5 | import 'package:gputest/julia.dart';
6 | import 'package:gputest/texture_cube.dart';
7 | import 'package:gputest/triangle.dart';
8 |
9 | void main() {
10 | runApp(const MyApp());
11 | }
12 |
13 | class MyApp extends StatelessWidget {
14 | const MyApp({super.key});
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | title: 'Flutter Demo',
20 | theme: ThemeData(
21 | colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
22 | useMaterial3: true,
23 | ),
24 | home: const DemoPage(),
25 | );
26 | }
27 | }
28 |
29 | class DemoPage extends StatefulWidget {
30 | const DemoPage({super.key});
31 |
32 | @override
33 | State createState() => _DemoPageState();
34 | }
35 |
36 | class _DemoPageState extends State {
37 | int widgetIndex = 0;
38 |
39 | @override
40 | Widget build(BuildContext context) {
41 | final widgets = [
42 | const ColorsPage(),
43 | const TextureCubePage(),
44 | const TrianglePage(),
45 | const JuliaSetPage()
46 | ];
47 | final widgetsNames = [
48 | 'ColorsPage() - vert/uniform example',
49 | 'TextureCubePage() - vert/indices/uniform/texture/depth example',
50 | 'TrianglePage() - vert/uniform example',
51 | 'JuliaSetPage() - Texture example'
52 | ];
53 | return Scaffold(
54 | appBar: AppBar(
55 | title: Row(
56 | children: [
57 | AnimatedOpacity(
58 | opacity: widgetIndex > 0 ? 1 : 0,
59 | duration: const Duration(milliseconds: 300),
60 | child: IconButton(
61 | onPressed: () => setState(() {
62 | widgetIndex = max(0, widgetIndex - 1);
63 | }),
64 | icon: const Icon(Icons.arrow_back_ios),
65 | ),
66 | ),
67 | Expanded(
68 | child: Text(
69 | 'GPU demo ${widgetsNames[widgetIndex]}',
70 | textAlign: TextAlign.center,
71 | )),
72 | AnimatedOpacity(
73 | opacity: widgetIndex < widgets.length - 1 ? 1 : 0,
74 | duration: const Duration(milliseconds: 300),
75 | child: IconButton(
76 | onPressed: () => setState(() {
77 | widgetIndex = min(widgets.length - 1, widgetIndex + 1);
78 | }),
79 | icon: const Icon(Icons.arrow_forward_ios),
80 | ),
81 | ),
82 | ],
83 | ),
84 | ),
85 | extendBodyBehindAppBar: false,
86 | body: Column(
87 | mainAxisAlignment: MainAxisAlignment.center,
88 | crossAxisAlignment: CrossAxisAlignment.center,
89 | children: [
90 | Expanded(child: widgets[widgetIndex]
91 | //child: IndexedStack(
92 | // index: widgetIndex,
93 | // children: widgets,
94 | //),
95 | ),
96 | ],
97 | ),
98 | );
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/lib/colors.dart:
--------------------------------------------------------------------------------
1 | import 'dart:typed_data';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/scheduler.dart';
5 |
6 | import 'package:flutter_gpu/gpu.dart' as gpu;
7 |
8 | import 'shaders.dart';
9 |
10 | ByteData float32(List values) {
11 | return Float32List.fromList(values).buffer.asByteData();
12 | }
13 |
14 | ByteData float32Mat(Matrix4 matrix) {
15 | return Float32List.fromList(matrix.storage).buffer.asByteData();
16 | }
17 |
18 |
19 | class ColorsPainter extends CustomPainter {
20 | ColorsPainter(this.red, this.green, this.blue);
21 |
22 | double red;
23 | double green;
24 | double blue;
25 |
26 | @override
27 | void paint(Canvas canvas, Size size) {
28 | /// Allocate a new renderable texture.
29 | final gpu.Texture? texture =
30 | gpu.gpuContext.createTexture(gpu.StorageMode.devicePrivate, 300, 300);
31 |
32 | final vertex = shaderLibrary['ColorsVertex']!;
33 | final fragment = shaderLibrary['ColorsFragment']!;
34 | final pipeline = gpu.gpuContext.createRenderPipeline(vertex, fragment);
35 |
36 | final gpu.DeviceBuffer? vertexBuffer = gpu.gpuContext
37 | .createDeviceBuffer(gpu.StorageMode.hostVisible, 4 * 6 * 3);
38 | vertexBuffer!.overwrite(Float32List.fromList([
39 | -0.5, -0.5, 1.0*red, 0.0, 0.0, 1.0, //
40 | 0, 0.5, 0.0, 1.0*green, 0.0, 1.0, //
41 | 0.5, -0.5, 0.0, 0.0, 1.0*blue, 1.0, //
42 | ]).buffer.asByteData());
43 |
44 | final commandBuffer = gpu.gpuContext.createCommandBuffer();
45 |
46 | final renderTarget = gpu.RenderTarget.singleColor(
47 | gpu.ColorAttachment(texture: texture!),
48 | );
49 | final pass = commandBuffer.createRenderPass(renderTarget);
50 |
51 | pass.bindPipeline(pipeline);
52 | pass.bindVertexBuffer(
53 | gpu.BufferView(vertexBuffer,
54 | offsetInBytes: 0, lengthInBytes: vertexBuffer.sizeInBytes), 3);
55 | pass.draw();
56 |
57 | commandBuffer.submit();
58 |
59 | /// Wrap the Flutter GPU texture as a ui.Image and draw it like normal!
60 | final image = texture.asImage();
61 |
62 | canvas.drawImage(image, Offset(-texture.width / 2, 0), Paint());
63 | }
64 |
65 | @override
66 | bool shouldRepaint(covariant CustomPainter oldDelegate) {
67 | return true;
68 | }
69 | }
70 |
71 | class ColorsPage extends StatefulWidget {
72 | const ColorsPage({super.key});
73 |
74 | @override
75 | State createState() => _ColorsPageState();
76 | }
77 |
78 | class _ColorsPageState extends State {
79 | Ticker? tick;
80 | double time = 0;
81 | double deltaSeconds = 0;
82 | double red = 1.0;
83 | double green = 1.0;
84 | double blue = 1.0;
85 |
86 | @override
87 | void initState() {
88 | tick = Ticker(
89 | (elapsed) {
90 | setState(() {
91 | double previousTime = time;
92 | time = elapsed.inMilliseconds / 1000.0;
93 | deltaSeconds = previousTime > 0 ? time - previousTime : 0;
94 | });
95 | },
96 | );
97 | tick!.start();
98 | super.initState();
99 | }
100 |
101 | @override
102 | Widget build(BuildContext context) {
103 | return Column(
104 | children: [
105 | Slider(
106 | value: red,
107 | max: 1,
108 | min: 0,
109 | onChanged: (value) => {setState(() => red = value)}),
110 | Slider(
111 | value: green,
112 | max: 1,
113 | min: 0,
114 | onChanged: (value) => {setState(() => green = value)}),
115 | Slider(
116 | value: blue,
117 | max: 1,
118 | min: 0,
119 | onChanged: (value) => {setState(() => blue = value)}),
120 | CustomPaint(
121 | painter: ColorsPainter(red, green, blue),
122 | ),
123 | ],
124 | );
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: gputest
2 | description: A new Flutter project.
3 | # The following line prevents the package from being accidentally published to
4 | # pub.dev using `flutter pub publish`. This is preferred for private packages.
5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
6 |
7 | # The following defines the version and build number for your application.
8 | # A version number is three numbers separated by dots, like 1.2.43
9 | # followed by an optional build number separated by a +.
10 | # Both the version and the builder number may be overridden in flutter
11 | # build by specifying --build-name and --build-number, respectively.
12 | # In Android, build-name is used as versionName while build-number used as versionCode.
13 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
14 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
15 | # Read more about iOS versioning at
16 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
17 | # In Windows, build-name is used as the major, minor, and patch parts
18 | # of the product and file versions while build-number is used as the build suffix.
19 | version: 1.0.0+1
20 |
21 | environment:
22 | sdk: '>=3.1.0-49.0.dev <4.0.0'
23 |
24 | # Dependencies specify other packages that your package needs in order to work.
25 | # To automatically upgrade your package dependencies to the latest versions
26 | # consider running `flutter pub upgrade --major-versions`. Alternatively,
27 | # dependencies can be manually updated by changing the version numbers below to
28 | # the latest version available on pub.dev. To see which dependencies have newer
29 | # versions available, run `flutter pub outdated`.
30 | dependencies:
31 | flutter:
32 | sdk: flutter
33 | flutter_gpu:
34 | sdk: flutter
35 |
36 |
37 | # The following adds the Cupertino Icons font to your application.
38 | # Use with the CupertinoIcons class for iOS style icons.
39 | cupertino_icons: ^1.0.2
40 | vector_math: ^2.1.4
41 | flutter_gpu_shaders: ^0.1.2
42 | native_assets_cli: ^0.7.3
43 |
44 | dev_dependencies:
45 | flutter_test:
46 | sdk: flutter
47 |
48 | # The "flutter_lints" package below contains a set of recommended lints to
49 | # encourage good coding practices. The lint set provided by the package is
50 | # activated in the `analysis_options.yaml` file located at the root of your
51 | # package. See that file for information about deactivating specific lint
52 | # rules and activating additional ones.
53 | flutter_lints: ^2.0.0
54 |
55 | # For information on the generic Dart part of this file, see the
56 | # following page: https://dart.dev/tools/pub/pubspec
57 |
58 | # The following section is specific to Flutter packages.
59 | flutter:
60 |
61 | # The following line ensures that the Material Icons font is
62 | # included with your application, so that you can use the icons in
63 | # the material Icons class.
64 | uses-material-design: true
65 |
66 | # To add assets to your application, add an assets section, like this:
67 | assets:
68 | - build/shaderbundles/TestLibrary.shaderbundle
69 | # - images/a_dot_burr.jpeg
70 | # - images/a_dot_ham.jpeg
71 |
72 | # An image asset can refer to one or more resolution-specific "variants", see
73 | # https://flutter.dev/assets-and-images/#resolution-aware
74 |
75 | # For details regarding adding assets from package dependencies, see
76 | # https://flutter.dev/assets-and-images/#from-packages
77 |
78 | # To add custom fonts to your application, add a fonts section here,
79 | # in this "flutter" section. Each entry in this list should have a
80 | # "family" key with the font family name, and a "fonts" key with a
81 | # list giving the asset and other descriptors for the font. For
82 | # example:
83 | # fonts:
84 | # - family: Schyler
85 | # fonts:
86 | # - asset: fonts/Schyler-Regular.ttf
87 | # - asset: fonts/Schyler-Italic.ttf
88 | # style: italic
89 | # - family: Trajan Pro
90 | # fonts:
91 | # - asset: fonts/TrajanPro.ttf
92 | # - asset: fonts/TrajanPro_Bold.ttf
93 | # weight: 700
94 | #
95 | # For details regarding fonts from package dependencies,
96 | # see https://flutter.dev/custom-fonts/#from-packages
97 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
43 |
49 |
50 |
51 |
52 |
53 |
65 |
67 |
73 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
88 |
90 |
96 |
97 |
98 |
99 |
101 |
102 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/lib/julia.dart:
--------------------------------------------------------------------------------
1 | import 'dart:typed_data';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/scheduler.dart';
5 | import 'dart:ui' as ui;
6 |
7 | import 'package:flutter_gpu/gpu.dart' as gpu;
8 |
9 | class JuliaSetPainter extends CustomPainter {
10 | JuliaSetPainter(this.time, this.seedX, this.seedY);
11 |
12 | double time;
13 | double seedX;
14 | double seedY;
15 | final maxIterations = 100;
16 | final escapeDistance = 10;
17 |
18 | @override
19 | void paint(Canvas canvas, Size size) {
20 | final gpu.Texture? texture =
21 | gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 21, 9); // keep width odd
22 | if (texture == null) {
23 | return;
24 | }
25 |
26 | // Illustrating creating a texture and using that to create image
27 | // The are arbitrary methods of filling buffer and transferring it to the texture
28 | // so that it changes via time and the sliders.
29 | if(seedX>0.0) {
30 | // flashing CHECKER BOARD of any size (works as long as width is odd)
31 | texture.overwrite(Uint32List.fromList(
32 |
33 | List.generate(texture.width*texture.height, (int index) {
34 | int onColor = seedY<0 ? (0xFF*seedY).toInt() | 0x00FFFF00 :
35 | (0xFF*-seedY).toInt()<<8 | 0x00FF00FF;
36 | return index.isEven ? (time.toInt().isEven ? onColor : 0xFF000000) : (time.toInt().isEven ? 0xFF000000 :onColor);
37 | }, growable: false) ).buffer.asByteData());
38 | //(oldway) fixed 3x3 checkerboard
39 | //texture.overwrite(Uint32List.fromList([
40 | // 0xFFFFFFFF, 0xFF000000, 0xFFFFFFFF, //
41 | // 0xFF000000, 0xFFFFFFFF, 0xFF000000, //
42 | // 0xFFFFFFFF, 0xFF000000, 0xFFFFFFFF, //
43 | //]).buffer.asByteData());
44 | } else {
45 | var buffer = Int32List(texture.width * texture.height);
46 | for (int i = 0; i < buffer.length; i++) {
47 | int xi = i % texture.width;
48 | int yi = i ~/ texture.width;
49 | double x = (xi.toDouble() - texture.width / 2) / (texture.width * 0.75);
50 | double y = (yi.toDouble() - texture.height / 2) / (texture.height * 0.75);
51 | int iterations = 0;
52 | for (int it = 0; it < maxIterations; it++) {
53 | // Square the complex number and add the seed offset.
54 | double newX = x * x - y * y + seedX;
55 | y = 2 * x * y + seedY;
56 | x = newX;
57 | if (x * x + y * y > escapeDistance * escapeDistance) {
58 | iterations = it;
59 | break;
60 | }
61 | }
62 | int shade = (iterations / maxIterations * 0xFF).toInt();
63 | buffer[i] = Color.fromARGB(0xFF, (shade*time).toInt(), (seedX*time).toInt(), (seedY*time).toInt()).value;
64 | }
65 |
66 | texture.overwrite(buffer.buffer.asByteData());
67 | }
68 |
69 | final ui.Image image = texture.asImage();
70 |
71 | canvas.scale(50);
72 | canvas.drawImage(image, Offset(-texture.width / 2, 0), Paint());
73 | }
74 |
75 | @override
76 | bool shouldRepaint(covariant CustomPainter oldDelegate) {
77 | return true;
78 | }
79 | }
80 |
81 | class JuliaSetPage extends StatefulWidget {
82 | const JuliaSetPage({super.key});
83 |
84 | @override
85 | State createState() => _JuliaSetPageState();
86 | }
87 |
88 | class _JuliaSetPageState extends State {
89 | Ticker? tick;
90 | double time = 0;
91 | double deltaSeconds = 0;
92 | double seedX = -0.512511498387847167;
93 | double seedY = 0.521295573094847167;
94 |
95 | @override
96 | void initState() {
97 | tick = Ticker(
98 | (elapsed) {
99 | setState(() {
100 | double previousTime = time;
101 | time = elapsed.inMilliseconds / 1000.0;
102 | deltaSeconds = previousTime > 0 ? time - previousTime : 0;
103 | });
104 | },
105 | );
106 | tick!.start();
107 | super.initState();
108 | }
109 |
110 | @override
111 | Widget build(BuildContext context) {
112 | return Column(
113 | children: [
114 | Slider(
115 | value: seedX,
116 | max: 1,
117 | min: -1,
118 | onChanged: (value) => {setState(() => seedX = value)}),
119 | Slider(
120 | value: seedY,
121 | max: 1,
122 | min: -1,
123 | onChanged: (value) => {setState(() => seedY = value)}),
124 | CustomPaint(
125 | painter: JuliaSetPainter(time, seedX, seedY),
126 | ),
127 | ],
128 | );
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/lib/triangle.dart:
--------------------------------------------------------------------------------
1 | import 'dart:typed_data';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/scheduler.dart';
5 |
6 | import 'package:flutter_gpu/gpu.dart' as gpu;
7 |
8 | import 'shaders.dart';
9 |
10 | ByteData float32(List values) {
11 | return Float32List.fromList(values).buffer.asByteData();
12 | }
13 |
14 | ByteData float32Mat(Matrix4 matrix) {
15 | return Float32List.fromList(matrix.storage).buffer.asByteData();
16 | }
17 |
18 | class TrianglePainter extends CustomPainter {
19 | TrianglePainter(this.time, this.seedX, this.seedY);
20 |
21 | double time;
22 | double seedX;
23 | double seedY;
24 |
25 | @override
26 | void paint(Canvas canvas, Size size) {
27 | /// Allocate a new renderable texture.
28 | final gpu.Texture? renderTexture = gpu.gpuContext.createTexture(
29 | gpu.StorageMode.devicePrivate, 300, 300,
30 | enableRenderTargetUsage: true,
31 | enableShaderReadUsage: true,
32 | coordinateSystem: gpu.TextureCoordinateSystem.renderToTexture);
33 | if (renderTexture == null) {
34 | return;
35 | }
36 |
37 | final gpu.Texture? depthTexture = gpu.gpuContext.createTexture(
38 | gpu.StorageMode.deviceTransient, 300, 300,
39 | format: gpu.gpuContext.defaultDepthStencilFormat,
40 | enableRenderTargetUsage: true,
41 | coordinateSystem: gpu.TextureCoordinateSystem.renderToTexture);
42 | if (depthTexture == null) {
43 | return;
44 | }
45 |
46 | /// Create the command buffer. This will be used to submit all encoded
47 | /// commands at the end.
48 | final commandBuffer = gpu.gpuContext.createCommandBuffer();
49 |
50 | /// Define a render target. This is just a collection of attachments that a
51 | /// RenderPass will write to.
52 | final renderTarget = gpu.RenderTarget.singleColor(
53 | gpu.ColorAttachment(texture: renderTexture),
54 | depthStencilAttachment: gpu.DepthStencilAttachment(texture: depthTexture),
55 | );
56 |
57 | /// Add a render pass encoder to the command buffer so that we can start
58 | /// encoding commands.
59 | final pass = commandBuffer.createRenderPass(renderTarget);
60 |
61 | /// Create a RenderPipeline using shaders from the asset.
62 | final vertex = shaderLibrary['UnlitVertex']!;
63 | final fragment = shaderLibrary['UnlitFragment']!;
64 | final pipeline = gpu.gpuContext.createRenderPipeline(vertex, fragment);
65 |
66 | pass.bindPipeline(pipeline);
67 |
68 | /// (Optional) Configure blending for the first color attachment.
69 | pass.setColorBlendEnable(true);
70 | pass.setColorBlendEquation(gpu.ColorBlendEquation(
71 | colorBlendOperation: gpu.BlendOperation.add,
72 | sourceColorBlendFactor: gpu.BlendFactor.one,
73 | destinationColorBlendFactor: gpu.BlendFactor.oneMinusSourceAlpha,
74 | alphaBlendOperation: gpu.BlendOperation.add,
75 | sourceAlphaBlendFactor: gpu.BlendFactor.one,
76 | destinationAlphaBlendFactor: gpu.BlendFactor.oneMinusSourceAlpha));
77 |
78 | /// Append quick geometry and uniforms to a host buffer that will be
79 | /// automatically uploaded to the GPU later on.
80 | final transients = gpu.gpuContext.createHostBuffer();
81 | final vertices = transients.emplace(float32([
82 | -0.5, -0.5, //
83 | 0, 0.5, //
84 | 0.5, -0.5, //
85 | ]));
86 |
87 |
88 | /// Bind the vertex data. In this case, we won't bother binding an index
89 | /// buffer.
90 | pass.bindVertexBuffer(vertices, 3);
91 |
92 | /* PreVulkanSupport - no longer possible because Vulkan has poor Uniform support
93 | and we can only do a single blob...
94 | final color = transients.emplace(float32([0, 1, 0, 1])); // rgba
95 | final mvp = transients.emplace(float32Mat(Matrix4(
96 | 1, 0, 0, 0, //
97 | 0, 1, 0, 0, //
98 | 0, 0, 1, 0, //
99 | 0, 0, 0.5, 1, //
100 | ) *
101 | Matrix4.rotationX(time) *
102 | Matrix4.rotationY(time * seedX) *
103 | Matrix4.rotationZ(time * seedY)));
104 |
105 | /// Bind the host buffer data we just created to the vertex shader's uniform
106 | /// slots. Although the locations are specified in the shader and are
107 | /// predictable, we can optionally fetch the uniform slots by name for
108 | /// convenience.
109 | final mvpSlot = pipeline.vertexShader.getUniformSlot('mvp')!;
110 | final colorSlot = pipeline.vertexShader.getUniformSlot('color')!;
111 | pass.bindUniform(mvpSlot, mvp);
112 | pass.bindUniform(colorSlot, color);
113 | PreVulkanSupport */
114 |
115 | final mvp = Matrix4(
116 | 1, 0, 0, 0, //
117 | 0, 1, 0, 0, //
118 | 0, 0, 1, 0, //
119 | 0, 0, 0.5, 1, //
120 | ) *
121 | Matrix4.rotationX(time) *
122 | Matrix4.rotationY(time * seedX) *
123 | Matrix4.rotationZ(time * seedY);
124 | final color = [0, 1, 0, 1]; // rgba
125 | // We must manually map the members of the 'FrameInfo' uniform struct with the
126 | // corresponding float data
127 | final frameInfoSlot = vertex.getUniformSlot('FrameInfo');
128 | final frameInfoFloats = Float32List.fromList([
129 | mvp.storage[0],
130 | mvp.storage[1],
131 | mvp.storage[2],
132 | mvp.storage[3],
133 | mvp.storage[4],
134 | mvp.storage[5],
135 | mvp.storage[6],
136 | mvp.storage[7],
137 | mvp.storage[8],
138 | mvp.storage[9],
139 | mvp.storage[10],
140 | mvp.storage[11],
141 | mvp.storage[12],
142 | mvp.storage[13],
143 | mvp.storage[14],
144 | mvp.storage[15],
145 | color[0], // r
146 | color[1], // g
147 | color[2], // b
148 | color[3], // a
149 | ]);
150 | final frameInfoView =
151 | transients.emplace(frameInfoFloats.buffer.asByteData());
152 | pass.bindUniform(frameInfoSlot, frameInfoView);
153 |
154 | /// And finally, we append a draw call.
155 | pass.draw();
156 |
157 | /// Submit all of the previously encoded passes. Passes are encoded in the
158 | /// same order they were created in.
159 | commandBuffer.submit();
160 |
161 | /// Wrap the Flutter GPU texture as a ui.Image and draw it like normal!
162 | final image = renderTexture.asImage();
163 |
164 | canvas.drawImage(image, Offset(-renderTexture.width / 2, 0), Paint());
165 | }
166 |
167 | @override
168 | bool shouldRepaint(covariant CustomPainter oldDelegate) {
169 | return true;
170 | }
171 | }
172 |
173 | class TrianglePage extends StatefulWidget {
174 | const TrianglePage({super.key});
175 |
176 | @override
177 | State createState() => _TrianglePageState();
178 | }
179 |
180 | class _TrianglePageState extends State {
181 | Ticker? tick;
182 | double time = 0;
183 | double deltaSeconds = 0;
184 | double seedX = -0.512511498387847167;
185 | double seedY = 0.521295573094847167;
186 |
187 | @override
188 | void initState() {
189 | tick = Ticker(
190 | (elapsed) {
191 | setState(() {
192 | double previousTime = time;
193 | time = elapsed.inMilliseconds / 1000.0;
194 | deltaSeconds = previousTime > 0 ? time - previousTime : 0;
195 | });
196 | },
197 | );
198 | tick!.start();
199 | super.initState();
200 | }
201 |
202 | @override
203 | Widget build(BuildContext context) {
204 | return Column(
205 | children: [
206 | Slider(
207 | value: seedX,
208 | max: 1,
209 | min: -1,
210 | onChanged: (value) => {setState(() => seedX = value)}),
211 | Slider(
212 | value: seedY,
213 | max: 1,
214 | min: -1,
215 | onChanged: (value) => {setState(() => seedY = value)}),
216 | CustomPaint(
217 | painter: TrianglePainter(time, seedX, seedY),
218 | ),
219 | ],
220 | );
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/lib/texture_cube.dart:
--------------------------------------------------------------------------------
1 | import 'dart:typed_data';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/scheduler.dart';
5 | import 'package:vector_math/vector_math_64.dart';
6 |
7 | import 'package:flutter_gpu/gpu.dart' as gpu;
8 |
9 | import 'shaders.dart';
10 |
11 | ByteData float32(List values) {
12 | return Float32List.fromList(values).buffer.asByteData();
13 | }
14 |
15 | ByteData uint16(List values) {
16 | return Uint16List.fromList(values).buffer.asByteData();
17 | }
18 |
19 | ByteData uint32(List values) {
20 | return Uint32List.fromList(values).buffer.asByteData();
21 | }
22 |
23 | ByteData float32Mat(Matrix4 matrix) {
24 | return Float32List.fromList(matrix.storage).buffer.asByteData();
25 | }
26 |
27 | class TextureCubePainter extends CustomPainter {
28 | TextureCubePainter(this.time, this.seedX, this.seedY,this.scale,this.depthClearValue);
29 |
30 | double time;
31 | double seedX;
32 | double seedY;
33 | double scale;
34 | double depthClearValue;
35 |
36 | @override
37 | void paint(Canvas canvas, Size size) {
38 | /// Allocate a new renderable texture.
39 | final gpu.Texture? renderTexture = gpu.gpuContext.createTexture(
40 | gpu.StorageMode.devicePrivate, 300, 300,
41 | enableRenderTargetUsage: true,
42 | enableShaderReadUsage: true,
43 | coordinateSystem: gpu.TextureCoordinateSystem.renderToTexture);
44 | if (renderTexture == null) {
45 | return;
46 | }
47 |
48 | final gpu.Texture? depthTexture = gpu.gpuContext.createTexture(
49 | gpu.StorageMode.deviceTransient, 300, 300,
50 | format: gpu.gpuContext.defaultDepthStencilFormat,
51 | enableRenderTargetUsage: true,
52 | coordinateSystem: gpu.TextureCoordinateSystem.renderToTexture);
53 | if (depthTexture == null) {
54 | return;
55 | }
56 |
57 | /// Create the command buffer. This will be used to submit all encoded
58 | /// commands at the end.
59 | final commandBuffer = gpu.gpuContext.createCommandBuffer();
60 |
61 | /// Define a render target. This is just a collection of attachments that a
62 | /// RenderPass will write to.
63 | final renderTarget = gpu.RenderTarget.singleColor(
64 | gpu.ColorAttachment(texture: renderTexture),
65 | depthStencilAttachment: gpu.DepthStencilAttachment(
66 | texture: depthTexture, depthClearValue: depthClearValue),
67 | );
68 |
69 | /// Add a render pass encoder to the command buffer so that we can start
70 | /// encoding commands.
71 | final pass = commandBuffer.createRenderPass(renderTarget);
72 |
73 | /// Create a RenderPipeline using shaders from the asset.
74 | final vertex = shaderLibrary['TextureVertex']!;
75 | final fragment = shaderLibrary['TextureFragment']!;
76 | final pipeline = gpu.gpuContext.createRenderPipeline(vertex, fragment);
77 |
78 | pass.bindPipeline(pipeline);
79 |
80 | pass.setDepthWriteEnable(true);
81 | pass.setDepthCompareOperation(gpu.CompareFunction.less);
82 |
83 | /// (Optional) Configure blending for the first color attachment.
84 | pass.setColorBlendEnable(true);
85 | pass.setColorBlendEquation(gpu.ColorBlendEquation(
86 | colorBlendOperation: gpu.BlendOperation.add,
87 | sourceColorBlendFactor: gpu.BlendFactor.one,
88 | destinationColorBlendFactor: gpu.BlendFactor.oneMinusSourceAlpha,
89 | alphaBlendOperation: gpu.BlendOperation.add,
90 | sourceAlphaBlendFactor: gpu.BlendFactor.one,
91 | destinationAlphaBlendFactor: gpu.BlendFactor.oneMinusSourceAlpha));
92 |
93 | /// Append quick geometry and uniforms to a host buffer that will be
94 | /// automatically uploaded to the GPU later on.
95 | final transients = gpu.gpuContext.createHostBuffer();
96 | final vertices = transients.emplace(float32([
97 | -1, -1, -1, /* */ 0, 0, /* */ 1, 0, 0, 1, //
98 | 1, -1, -1, /* */ 1, 0, /* */ 0, 1, 0, 1, //
99 | 1, 1, -1, /* */ 1, 1, /* */ 0, 0, 1, 1, //
100 | -1, 1, -1, /* */ 0, 1, /* */ 0, 0, 0, 1, //
101 | -1, -1, 1, /* */ 0, 0, /* */ 0, 1, 1, 1, //
102 | 1, -1, 1, /* */ 1, 0, /* */ 1, 0, 1, 1, //
103 | 1, 1, 1, /* */ 1, 1, /* */ 1, 1, 0, 1, //
104 | -1, 1, 1, /* */ 0, 1, /* */ 1, 1, 1, 1, //
105 | ]));
106 | final indices = transients.emplace(uint16([
107 | 0, 1, 3, 3, 1, 2, //
108 | 1, 5, 2, 2, 5, 6, //
109 | 5, 4, 6, 6, 4, 7, //
110 | 4, 0, 7, 7, 0, 3, //
111 | 3, 2, 7, 7, 2, 6, //
112 | 4, 5, 0, 0, 5, 1, //
113 | ]));
114 | final mvp = transients.emplace(float32Mat(Matrix4(
115 | 0.5, 0, 0, 0, //
116 | 0, 0.5, 0, 0, //
117 | 0, 0, 0.2, 0, //
118 | 0, 0, 0.5, 1, //
119 | ) *
120 | Matrix4.rotationX(time) *
121 | Matrix4.rotationY(time * seedX) *
122 | Matrix4.rotationZ(time * seedY) *
123 | Matrix4.diagonal3( Vector3(scale,scale,scale))
124 | ));
125 | /// Bind the vertex and index buffer.
126 | pass.bindVertexBuffer(vertices, 8);
127 | pass.bindIndexBuffer(indices, gpu.IndexType.int16, 36);
128 |
129 | /// Bind the host buffer data we just created to the vertex shader's uniform
130 | /// slots. Although the locations are specified in the shader and are
131 | /// predictable, we can optionally fetch the uniform slots by name for
132 | /// convenience.
133 | final frameInfoSlot = vertex.getUniformSlot('FrameInfo');
134 | pass.bindUniform(frameInfoSlot, mvp);
135 |
136 | final sampledTexture = gpu.gpuContext.createTexture(
137 | gpu.StorageMode.hostVisible, 5, 5,
138 | enableShaderReadUsage: true);
139 | sampledTexture!.overwrite(uint32([
140 | 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, //
141 | 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, //
142 | 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, //
143 | 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, //
144 | 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, //
145 | ]));
146 |
147 | final texSlot = pipeline.fragmentShader.getUniformSlot('tex');
148 | pass.bindTexture(texSlot, sampledTexture);
149 |
150 | /// And finally, we append a draw call.
151 | pass.draw();
152 |
153 | /// Submit all of the previously encoded passes. Passes are encoded in the
154 | /// same order they were created in.
155 | commandBuffer.submit();
156 |
157 | /// Wrap the Flutter GPU texture as a ui.Image and draw it like normal!
158 | final image = renderTexture.asImage();
159 |
160 | canvas.drawImage(image, Offset(-renderTexture.width / 2, 0), Paint());
161 | }
162 |
163 | @override
164 | bool shouldRepaint(covariant CustomPainter oldDelegate) {
165 | return true;
166 | }
167 | }
168 |
169 | class TextureCubePage extends StatefulWidget {
170 | const TextureCubePage({super.key});
171 |
172 | @override
173 | State createState() => _TextureCubePageState();
174 | }
175 |
176 | class _TextureCubePageState extends State {
177 | Ticker? tick;
178 | double time = 0;
179 | double deltaSeconds = 0;
180 | double seedX = -0.512511498387847167;
181 | double seedY = 0.521295573094847167;
182 | double scale = 1.0;
183 | double depthClearValue = 1.0;
184 |
185 | @override
186 | void initState() {
187 | tick = Ticker(
188 | (elapsed) {
189 | setState(() {
190 | double previousTime = time;
191 | time = elapsed.inMilliseconds / 1000.0;
192 | deltaSeconds = previousTime > 0 ? time - previousTime : 0;
193 | });
194 | },
195 | );
196 | tick!.start();
197 | super.initState();
198 | }
199 |
200 | @override
201 | Widget build(BuildContext context) {
202 | return Column(
203 | children: [
204 | Slider(
205 | value: seedX,
206 | max: 1,
207 | min: -1,
208 | onChanged: (value) => {setState(() => seedX = value)}),
209 | Slider(
210 | value: seedY,
211 | max: 1,
212 | min: -1,
213 | onChanged: (value) => {setState(() => seedY = value)}),
214 | Slider(
215 | value: scale,
216 | max: 3,
217 | min: 0.1,
218 | onChanged: (value) => {setState(() => scale = value)}),
219 | Slider(
220 | value: depthClearValue,
221 | max: 1,
222 | min: 0,
223 | onChanged: (value) => {setState(() => depthClearValue = value)}),
224 | CustomPaint(
225 | painter: TextureCubePainter(time, seedX, seedY, scale, depthClearValue),
226 | ),
227 | ],
228 | );
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | _fe_analyzer_shared:
5 | dependency: transitive
6 | description:
7 | name: _fe_analyzer_shared
8 | sha256: "45cfa8471b89fb6643fe9bf51bd7931a76b8f5ec2d65de4fb176dba8d4f22c77"
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "73.0.0"
12 | _macros:
13 | dependency: transitive
14 | description: dart
15 | source: sdk
16 | version: "0.3.2"
17 | analyzer:
18 | dependency: transitive
19 | description:
20 | name: analyzer
21 | sha256: "4959fec185fe70cce007c57e9ab6983101dbe593d2bf8bbfb4453aaec0cf470a"
22 | url: "https://pub.dev"
23 | source: hosted
24 | version: "6.8.0"
25 | args:
26 | dependency: transitive
27 | description:
28 | name: args
29 | sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
30 | url: "https://pub.dev"
31 | source: hosted
32 | version: "2.5.0"
33 | async:
34 | dependency: transitive
35 | description:
36 | name: async
37 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
38 | url: "https://pub.dev"
39 | source: hosted
40 | version: "2.11.0"
41 | boolean_selector:
42 | dependency: transitive
43 | description:
44 | name: boolean_selector
45 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
46 | url: "https://pub.dev"
47 | source: hosted
48 | version: "2.1.1"
49 | characters:
50 | dependency: transitive
51 | description:
52 | name: characters
53 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
54 | url: "https://pub.dev"
55 | source: hosted
56 | version: "1.3.0"
57 | cli_config:
58 | dependency: transitive
59 | description:
60 | name: cli_config
61 | sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
62 | url: "https://pub.dev"
63 | source: hosted
64 | version: "0.2.0"
65 | clock:
66 | dependency: transitive
67 | description:
68 | name: clock
69 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
70 | url: "https://pub.dev"
71 | source: hosted
72 | version: "1.1.1"
73 | collection:
74 | dependency: transitive
75 | description:
76 | name: collection
77 | sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
78 | url: "https://pub.dev"
79 | source: hosted
80 | version: "1.19.0"
81 | convert:
82 | dependency: transitive
83 | description:
84 | name: convert
85 | sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
86 | url: "https://pub.dev"
87 | source: hosted
88 | version: "3.1.1"
89 | coverage:
90 | dependency: transitive
91 | description:
92 | name: coverage
93 | sha256: c1fb2dce3c0085f39dc72668e85f8e0210ec7de05345821ff58530567df345a5
94 | url: "https://pub.dev"
95 | source: hosted
96 | version: "1.9.2"
97 | crypto:
98 | dependency: transitive
99 | description:
100 | name: crypto
101 | sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
102 | url: "https://pub.dev"
103 | source: hosted
104 | version: "3.0.5"
105 | cupertino_icons:
106 | dependency: "direct main"
107 | description:
108 | name: cupertino_icons
109 | sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
110 | url: "https://pub.dev"
111 | source: hosted
112 | version: "1.0.5"
113 | fake_async:
114 | dependency: transitive
115 | description:
116 | name: fake_async
117 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
118 | url: "https://pub.dev"
119 | source: hosted
120 | version: "1.3.1"
121 | file:
122 | dependency: transitive
123 | description:
124 | name: file
125 | sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
126 | url: "https://pub.dev"
127 | source: hosted
128 | version: "7.0.0"
129 | flutter:
130 | dependency: "direct main"
131 | description: flutter
132 | source: sdk
133 | version: "0.0.0"
134 | flutter_gpu:
135 | dependency: "direct main"
136 | description: flutter
137 | source: sdk
138 | version: "0.0.0"
139 | flutter_gpu_shaders:
140 | dependency: "direct main"
141 | description:
142 | name: flutter_gpu_shaders
143 | sha256: "5f7d1c2ef7b0124c09b4cbbe71e2b483b706d064c21fbb46d2882702a3667b83"
144 | url: "https://pub.dev"
145 | source: hosted
146 | version: "0.1.2"
147 | flutter_lints:
148 | dependency: "direct dev"
149 | description:
150 | name: flutter_lints
151 | sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
152 | url: "https://pub.dev"
153 | source: hosted
154 | version: "2.0.1"
155 | flutter_test:
156 | dependency: "direct dev"
157 | description: flutter
158 | source: sdk
159 | version: "0.0.0"
160 | frontend_server_client:
161 | dependency: transitive
162 | description:
163 | name: frontend_server_client
164 | sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
165 | url: "https://pub.dev"
166 | source: hosted
167 | version: "4.0.0"
168 | glob:
169 | dependency: transitive
170 | description:
171 | name: glob
172 | sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
173 | url: "https://pub.dev"
174 | source: hosted
175 | version: "2.1.2"
176 | http_multi_server:
177 | dependency: transitive
178 | description:
179 | name: http_multi_server
180 | sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
181 | url: "https://pub.dev"
182 | source: hosted
183 | version: "3.2.1"
184 | http_parser:
185 | dependency: transitive
186 | description:
187 | name: http_parser
188 | sha256: "40f592dd352890c3b60fec1b68e786cefb9603e05ff303dbc4dda49b304ecdf4"
189 | url: "https://pub.dev"
190 | source: hosted
191 | version: "4.1.0"
192 | io:
193 | dependency: transitive
194 | description:
195 | name: io
196 | sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
197 | url: "https://pub.dev"
198 | source: hosted
199 | version: "1.0.4"
200 | js:
201 | dependency: transitive
202 | description:
203 | name: js
204 | sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
205 | url: "https://pub.dev"
206 | source: hosted
207 | version: "0.7.1"
208 | leak_tracker:
209 | dependency: transitive
210 | description:
211 | name: leak_tracker
212 | sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
213 | url: "https://pub.dev"
214 | source: hosted
215 | version: "10.0.7"
216 | leak_tracker_flutter_testing:
217 | dependency: transitive
218 | description:
219 | name: leak_tracker_flutter_testing
220 | sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
221 | url: "https://pub.dev"
222 | source: hosted
223 | version: "3.0.8"
224 | leak_tracker_testing:
225 | dependency: transitive
226 | description:
227 | name: leak_tracker_testing
228 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
229 | url: "https://pub.dev"
230 | source: hosted
231 | version: "3.0.1"
232 | lints:
233 | dependency: transitive
234 | description:
235 | name: lints
236 | sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015"
237 | url: "https://pub.dev"
238 | source: hosted
239 | version: "2.1.0"
240 | logging:
241 | dependency: transitive
242 | description:
243 | name: logging
244 | sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
245 | url: "https://pub.dev"
246 | source: hosted
247 | version: "1.2.0"
248 | macros:
249 | dependency: transitive
250 | description:
251 | name: macros
252 | sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
253 | url: "https://pub.dev"
254 | source: hosted
255 | version: "0.1.2-main.4"
256 | matcher:
257 | dependency: transitive
258 | description:
259 | name: matcher
260 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
261 | url: "https://pub.dev"
262 | source: hosted
263 | version: "0.12.16+1"
264 | material_color_utilities:
265 | dependency: transitive
266 | description:
267 | name: material_color_utilities
268 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
269 | url: "https://pub.dev"
270 | source: hosted
271 | version: "0.11.1"
272 | meta:
273 | dependency: transitive
274 | description:
275 | name: meta
276 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
277 | url: "https://pub.dev"
278 | source: hosted
279 | version: "1.15.0"
280 | mime:
281 | dependency: transitive
282 | description:
283 | name: mime
284 | sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
285 | url: "https://pub.dev"
286 | source: hosted
287 | version: "1.0.6"
288 | native_assets_cli:
289 | dependency: "direct main"
290 | description:
291 | name: native_assets_cli
292 | sha256: "1ff032c0ca050391c4c5107485f1a26e0e95cee18d1fdb2b7bdbb990efd3c188"
293 | url: "https://pub.dev"
294 | source: hosted
295 | version: "0.7.3"
296 | node_preamble:
297 | dependency: transitive
298 | description:
299 | name: node_preamble
300 | sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
301 | url: "https://pub.dev"
302 | source: hosted
303 | version: "2.0.2"
304 | package_config:
305 | dependency: transitive
306 | description:
307 | name: package_config
308 | sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
309 | url: "https://pub.dev"
310 | source: hosted
311 | version: "2.1.0"
312 | path:
313 | dependency: transitive
314 | description:
315 | name: path
316 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
317 | url: "https://pub.dev"
318 | source: hosted
319 | version: "1.9.0"
320 | pool:
321 | dependency: transitive
322 | description:
323 | name: pool
324 | sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
325 | url: "https://pub.dev"
326 | source: hosted
327 | version: "1.5.1"
328 | pub_semver:
329 | dependency: transitive
330 | description:
331 | name: pub_semver
332 | sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
333 | url: "https://pub.dev"
334 | source: hosted
335 | version: "2.1.4"
336 | shelf:
337 | dependency: transitive
338 | description:
339 | name: shelf
340 | sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
341 | url: "https://pub.dev"
342 | source: hosted
343 | version: "1.4.2"
344 | shelf_packages_handler:
345 | dependency: transitive
346 | description:
347 | name: shelf_packages_handler
348 | sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
349 | url: "https://pub.dev"
350 | source: hosted
351 | version: "3.0.2"
352 | shelf_static:
353 | dependency: transitive
354 | description:
355 | name: shelf_static
356 | sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e
357 | url: "https://pub.dev"
358 | source: hosted
359 | version: "1.1.2"
360 | shelf_web_socket:
361 | dependency: transitive
362 | description:
363 | name: shelf_web_socket
364 | sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
365 | url: "https://pub.dev"
366 | source: hosted
367 | version: "2.0.0"
368 | sky_engine:
369 | dependency: transitive
370 | description: flutter
371 | source: sdk
372 | version: "0.0.0"
373 | source_map_stack_trace:
374 | dependency: transitive
375 | description:
376 | name: source_map_stack_trace
377 | sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
378 | url: "https://pub.dev"
379 | source: hosted
380 | version: "2.1.2"
381 | source_maps:
382 | dependency: transitive
383 | description:
384 | name: source_maps
385 | sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703"
386 | url: "https://pub.dev"
387 | source: hosted
388 | version: "0.10.12"
389 | source_span:
390 | dependency: transitive
391 | description:
392 | name: source_span
393 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
394 | url: "https://pub.dev"
395 | source: hosted
396 | version: "1.10.0"
397 | stack_trace:
398 | dependency: transitive
399 | description:
400 | name: stack_trace
401 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
402 | url: "https://pub.dev"
403 | source: hosted
404 | version: "1.11.1"
405 | stream_channel:
406 | dependency: transitive
407 | description:
408 | name: stream_channel
409 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
410 | url: "https://pub.dev"
411 | source: hosted
412 | version: "2.1.2"
413 | string_scanner:
414 | dependency: transitive
415 | description:
416 | name: string_scanner
417 | sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
418 | url: "https://pub.dev"
419 | source: hosted
420 | version: "1.3.0"
421 | term_glyph:
422 | dependency: transitive
423 | description:
424 | name: term_glyph
425 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
426 | url: "https://pub.dev"
427 | source: hosted
428 | version: "1.2.1"
429 | test:
430 | dependency: transitive
431 | description:
432 | name: test
433 | sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f"
434 | url: "https://pub.dev"
435 | source: hosted
436 | version: "1.25.8"
437 | test_api:
438 | dependency: transitive
439 | description:
440 | name: test_api
441 | sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
442 | url: "https://pub.dev"
443 | source: hosted
444 | version: "0.7.3"
445 | test_core:
446 | dependency: transitive
447 | description:
448 | name: test_core
449 | sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d"
450 | url: "https://pub.dev"
451 | source: hosted
452 | version: "0.6.5"
453 | typed_data:
454 | dependency: transitive
455 | description:
456 | name: typed_data
457 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
458 | url: "https://pub.dev"
459 | source: hosted
460 | version: "1.3.2"
461 | vector_math:
462 | dependency: "direct main"
463 | description:
464 | name: vector_math
465 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
466 | url: "https://pub.dev"
467 | source: hosted
468 | version: "2.1.4"
469 | vm_service:
470 | dependency: transitive
471 | description:
472 | name: vm_service
473 | sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
474 | url: "https://pub.dev"
475 | source: hosted
476 | version: "14.2.5"
477 | watcher:
478 | dependency: transitive
479 | description:
480 | name: watcher
481 | sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
482 | url: "https://pub.dev"
483 | source: hosted
484 | version: "1.1.0"
485 | web:
486 | dependency: transitive
487 | description:
488 | name: web
489 | sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
490 | url: "https://pub.dev"
491 | source: hosted
492 | version: "1.0.0"
493 | web_socket:
494 | dependency: transitive
495 | description:
496 | name: web_socket
497 | sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
498 | url: "https://pub.dev"
499 | source: hosted
500 | version: "0.1.6"
501 | web_socket_channel:
502 | dependency: transitive
503 | description:
504 | name: web_socket_channel
505 | sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
506 | url: "https://pub.dev"
507 | source: hosted
508 | version: "3.0.1"
509 | webkit_inspection_protocol:
510 | dependency: transitive
511 | description:
512 | name: webkit_inspection_protocol
513 | sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
514 | url: "https://pub.dev"
515 | source: hosted
516 | version: "1.2.1"
517 | yaml:
518 | dependency: transitive
519 | description:
520 | name: yaml
521 | sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
522 | url: "https://pub.dev"
523 | source: hosted
524 | version: "3.1.2"
525 | sdks:
526 | dart: ">=3.4.0 <4.0.0"
527 | flutter: ">=3.18.0-18.0.pre.54"
528 |
--------------------------------------------------------------------------------
/macos/Runner/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXAggregateTarget section */
10 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = {
11 | isa = PBXAggregateTarget;
12 | buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */;
13 | buildPhases = (
14 | 33CC111E2044C6BF0003C045 /* ShellScript */,
15 | );
16 | dependencies = (
17 | );
18 | name = "Flutter Assemble";
19 | productName = FLX;
20 | };
21 | /* End PBXAggregateTarget section */
22 |
23 | /* Begin PBXBuildFile section */
24 | 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; };
25 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
26 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
27 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
28 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
29 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
30 | /* End PBXBuildFile section */
31 |
32 | /* Begin PBXContainerItemProxy section */
33 | 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = {
34 | isa = PBXContainerItemProxy;
35 | containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
36 | proxyType = 1;
37 | remoteGlobalIDString = 33CC10EC2044A3C60003C045;
38 | remoteInfo = Runner;
39 | };
40 | 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = {
41 | isa = PBXContainerItemProxy;
42 | containerPortal = 33CC10E52044A3C60003C045 /* Project object */;
43 | proxyType = 1;
44 | remoteGlobalIDString = 33CC111A2044C6BA0003C045;
45 | remoteInfo = FLX;
46 | };
47 | /* End PBXContainerItemProxy section */
48 |
49 | /* Begin PBXCopyFilesBuildPhase section */
50 | 33CC110E2044A8840003C045 /* Bundle Framework */ = {
51 | isa = PBXCopyFilesBuildPhase;
52 | buildActionMask = 2147483647;
53 | dstPath = "";
54 | dstSubfolderSpec = 10;
55 | files = (
56 | );
57 | name = "Bundle Framework";
58 | runOnlyForDeploymentPostprocessing = 0;
59 | };
60 | /* End PBXCopyFilesBuildPhase section */
61 |
62 | /* Begin PBXFileReference section */
63 | 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
64 | 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
65 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; };
66 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; };
67 | 33CC10ED2044A3C60003C045 /* gputest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "gputest.app"; sourceTree = BUILT_PRODUCTS_DIR; };
68 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
69 | 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; };
70 | 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
71 | 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; };
72 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; };
73 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; };
74 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; };
75 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; };
76 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; };
77 | 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; };
78 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; };
79 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; };
80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; };
81 | /* End PBXFileReference section */
82 |
83 | /* Begin PBXFrameworksBuildPhase section */
84 | 331C80D2294CF70F00263BE5 /* Frameworks */ = {
85 | isa = PBXFrameworksBuildPhase;
86 | buildActionMask = 2147483647;
87 | files = (
88 | );
89 | runOnlyForDeploymentPostprocessing = 0;
90 | };
91 | 33CC10EA2044A3C60003C045 /* Frameworks */ = {
92 | isa = PBXFrameworksBuildPhase;
93 | buildActionMask = 2147483647;
94 | files = (
95 | );
96 | runOnlyForDeploymentPostprocessing = 0;
97 | };
98 | /* End PBXFrameworksBuildPhase section */
99 |
100 | /* Begin PBXGroup section */
101 | 331C80D6294CF71000263BE5 /* RunnerTests */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 331C80D7294CF71000263BE5 /* RunnerTests.swift */,
105 | );
106 | path = RunnerTests;
107 | sourceTree = "";
108 | };
109 | 33BA886A226E78AF003329D5 /* Configs */ = {
110 | isa = PBXGroup;
111 | children = (
112 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */,
113 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
114 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
115 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */,
116 | );
117 | path = Configs;
118 | sourceTree = "";
119 | };
120 | 33CC10E42044A3C60003C045 = {
121 | isa = PBXGroup;
122 | children = (
123 | 33FAB671232836740065AC1E /* Runner */,
124 | 33CEB47122A05771004F2AC0 /* Flutter */,
125 | 331C80D6294CF71000263BE5 /* RunnerTests */,
126 | 33CC10EE2044A3C60003C045 /* Products */,
127 | D73912EC22F37F3D000D13A0 /* Frameworks */,
128 | );
129 | sourceTree = "";
130 | };
131 | 33CC10EE2044A3C60003C045 /* Products */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 33CC10ED2044A3C60003C045 /* gputest.app */,
135 | 331C80D5294CF71000263BE5 /* RunnerTests.xctest */,
136 | );
137 | name = Products;
138 | sourceTree = "";
139 | };
140 | 33CC11242044D66E0003C045 /* Resources */ = {
141 | isa = PBXGroup;
142 | children = (
143 | 33CC10F22044A3C60003C045 /* Assets.xcassets */,
144 | 33CC10F42044A3C60003C045 /* MainMenu.xib */,
145 | 33CC10F72044A3C60003C045 /* Info.plist */,
146 | );
147 | name = Resources;
148 | path = ..;
149 | sourceTree = "";
150 | };
151 | 33CEB47122A05771004F2AC0 /* Flutter */ = {
152 | isa = PBXGroup;
153 | children = (
154 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */,
155 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
156 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
157 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
158 | );
159 | path = Flutter;
160 | sourceTree = "";
161 | };
162 | 33FAB671232836740065AC1E /* Runner */ = {
163 | isa = PBXGroup;
164 | children = (
165 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */,
166 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */,
167 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */,
168 | 33E51914231749380026EE4D /* Release.entitlements */,
169 | 33CC11242044D66E0003C045 /* Resources */,
170 | 33BA886A226E78AF003329D5 /* Configs */,
171 | );
172 | path = Runner;
173 | sourceTree = "";
174 | };
175 | D73912EC22F37F3D000D13A0 /* Frameworks */ = {
176 | isa = PBXGroup;
177 | children = (
178 | );
179 | name = Frameworks;
180 | sourceTree = "";
181 | };
182 | /* End PBXGroup section */
183 |
184 | /* Begin PBXNativeTarget section */
185 | 331C80D4294CF70F00263BE5 /* RunnerTests */ = {
186 | isa = PBXNativeTarget;
187 | buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
188 | buildPhases = (
189 | 331C80D1294CF70F00263BE5 /* Sources */,
190 | 331C80D2294CF70F00263BE5 /* Frameworks */,
191 | 331C80D3294CF70F00263BE5 /* Resources */,
192 | );
193 | buildRules = (
194 | );
195 | dependencies = (
196 | 331C80DA294CF71000263BE5 /* PBXTargetDependency */,
197 | );
198 | name = RunnerTests;
199 | productName = RunnerTests;
200 | productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */;
201 | productType = "com.apple.product-type.bundle.unit-test";
202 | };
203 | 33CC10EC2044A3C60003C045 /* Runner */ = {
204 | isa = PBXNativeTarget;
205 | buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
206 | buildPhases = (
207 | 33CC10E92044A3C60003C045 /* Sources */,
208 | 33CC10EA2044A3C60003C045 /* Frameworks */,
209 | 33CC10EB2044A3C60003C045 /* Resources */,
210 | 33CC110E2044A8840003C045 /* Bundle Framework */,
211 | 3399D490228B24CF009A79C7 /* ShellScript */,
212 | );
213 | buildRules = (
214 | );
215 | dependencies = (
216 | 33CC11202044C79F0003C045 /* PBXTargetDependency */,
217 | );
218 | name = Runner;
219 | productName = Runner;
220 | productReference = 33CC10ED2044A3C60003C045 /* gputest.app */;
221 | productType = "com.apple.product-type.application";
222 | };
223 | /* End PBXNativeTarget section */
224 |
225 | /* Begin PBXProject section */
226 | 33CC10E52044A3C60003C045 /* Project object */ = {
227 | isa = PBXProject;
228 | attributes = {
229 | LastSwiftUpdateCheck = 0920;
230 | LastUpgradeCheck = 1510;
231 | ORGANIZATIONNAME = "";
232 | TargetAttributes = {
233 | 331C80D4294CF70F00263BE5 = {
234 | CreatedOnToolsVersion = 14.0;
235 | TestTargetID = 33CC10EC2044A3C60003C045;
236 | };
237 | 33CC10EC2044A3C60003C045 = {
238 | CreatedOnToolsVersion = 9.2;
239 | LastSwiftMigration = 1100;
240 | ProvisioningStyle = Automatic;
241 | SystemCapabilities = {
242 | com.apple.Sandbox = {
243 | enabled = 1;
244 | };
245 | };
246 | };
247 | 33CC111A2044C6BA0003C045 = {
248 | CreatedOnToolsVersion = 9.2;
249 | ProvisioningStyle = Manual;
250 | };
251 | };
252 | };
253 | buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
254 | compatibilityVersion = "Xcode 9.3";
255 | developmentRegion = en;
256 | hasScannedForEncodings = 0;
257 | knownRegions = (
258 | en,
259 | Base,
260 | );
261 | mainGroup = 33CC10E42044A3C60003C045;
262 | productRefGroup = 33CC10EE2044A3C60003C045 /* Products */;
263 | projectDirPath = "";
264 | projectRoot = "";
265 | targets = (
266 | 33CC10EC2044A3C60003C045 /* Runner */,
267 | 331C80D4294CF70F00263BE5 /* RunnerTests */,
268 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */,
269 | );
270 | };
271 | /* End PBXProject section */
272 |
273 | /* Begin PBXResourcesBuildPhase section */
274 | 331C80D3294CF70F00263BE5 /* Resources */ = {
275 | isa = PBXResourcesBuildPhase;
276 | buildActionMask = 2147483647;
277 | files = (
278 | );
279 | runOnlyForDeploymentPostprocessing = 0;
280 | };
281 | 33CC10EB2044A3C60003C045 /* Resources */ = {
282 | isa = PBXResourcesBuildPhase;
283 | buildActionMask = 2147483647;
284 | files = (
285 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */,
286 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */,
287 | );
288 | runOnlyForDeploymentPostprocessing = 0;
289 | };
290 | /* End PBXResourcesBuildPhase section */
291 |
292 | /* Begin PBXShellScriptBuildPhase section */
293 | 3399D490228B24CF009A79C7 /* ShellScript */ = {
294 | isa = PBXShellScriptBuildPhase;
295 | alwaysOutOfDate = 1;
296 | buildActionMask = 2147483647;
297 | files = (
298 | );
299 | inputFileListPaths = (
300 | );
301 | inputPaths = (
302 | );
303 | outputFileListPaths = (
304 | );
305 | outputPaths = (
306 | );
307 | runOnlyForDeploymentPostprocessing = 0;
308 | shellPath = /bin/sh;
309 | shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
310 | };
311 | 33CC111E2044C6BF0003C045 /* ShellScript */ = {
312 | isa = PBXShellScriptBuildPhase;
313 | buildActionMask = 2147483647;
314 | files = (
315 | );
316 | inputFileListPaths = (
317 | Flutter/ephemeral/FlutterInputs.xcfilelist,
318 | );
319 | inputPaths = (
320 | Flutter/ephemeral/tripwire,
321 | );
322 | outputFileListPaths = (
323 | Flutter/ephemeral/FlutterOutputs.xcfilelist,
324 | );
325 | outputPaths = (
326 | );
327 | runOnlyForDeploymentPostprocessing = 0;
328 | shellPath = /bin/sh;
329 | shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
330 | };
331 | /* End PBXShellScriptBuildPhase section */
332 |
333 | /* Begin PBXSourcesBuildPhase section */
334 | 331C80D1294CF70F00263BE5 /* Sources */ = {
335 | isa = PBXSourcesBuildPhase;
336 | buildActionMask = 2147483647;
337 | files = (
338 | 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */,
339 | );
340 | runOnlyForDeploymentPostprocessing = 0;
341 | };
342 | 33CC10E92044A3C60003C045 /* Sources */ = {
343 | isa = PBXSourcesBuildPhase;
344 | buildActionMask = 2147483647;
345 | files = (
346 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */,
347 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */,
348 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */,
349 | );
350 | runOnlyForDeploymentPostprocessing = 0;
351 | };
352 | /* End PBXSourcesBuildPhase section */
353 |
354 | /* Begin PBXTargetDependency section */
355 | 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = {
356 | isa = PBXTargetDependency;
357 | target = 33CC10EC2044A3C60003C045 /* Runner */;
358 | targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */;
359 | };
360 | 33CC11202044C79F0003C045 /* PBXTargetDependency */ = {
361 | isa = PBXTargetDependency;
362 | target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */;
363 | targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */;
364 | };
365 | /* End PBXTargetDependency section */
366 |
367 | /* Begin PBXVariantGroup section */
368 | 33CC10F42044A3C60003C045 /* MainMenu.xib */ = {
369 | isa = PBXVariantGroup;
370 | children = (
371 | 33CC10F52044A3C60003C045 /* Base */,
372 | );
373 | name = MainMenu.xib;
374 | path = Runner;
375 | sourceTree = "";
376 | };
377 | /* End PBXVariantGroup section */
378 |
379 | /* Begin XCBuildConfiguration section */
380 | 331C80DB294CF71000263BE5 /* Debug */ = {
381 | isa = XCBuildConfiguration;
382 | buildSettings = {
383 | BUNDLE_LOADER = "$(TEST_HOST)";
384 | CURRENT_PROJECT_VERSION = 1;
385 | GENERATE_INFOPLIST_FILE = YES;
386 | MARKETING_VERSION = 1.0;
387 | PRODUCT_BUNDLE_IDENTIFIER = com.example.gputest.RunnerTests;
388 | PRODUCT_NAME = "$(TARGET_NAME)";
389 | SWIFT_VERSION = 5.0;
390 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gputest.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gputest";
391 | };
392 | name = Debug;
393 | };
394 | 331C80DC294CF71000263BE5 /* Release */ = {
395 | isa = XCBuildConfiguration;
396 | buildSettings = {
397 | BUNDLE_LOADER = "$(TEST_HOST)";
398 | CURRENT_PROJECT_VERSION = 1;
399 | GENERATE_INFOPLIST_FILE = YES;
400 | MARKETING_VERSION = 1.0;
401 | PRODUCT_BUNDLE_IDENTIFIER = com.example.gputest.RunnerTests;
402 | PRODUCT_NAME = "$(TARGET_NAME)";
403 | SWIFT_VERSION = 5.0;
404 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gputest.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gputest";
405 | };
406 | name = Release;
407 | };
408 | 331C80DD294CF71000263BE5 /* Profile */ = {
409 | isa = XCBuildConfiguration;
410 | buildSettings = {
411 | BUNDLE_LOADER = "$(TEST_HOST)";
412 | CURRENT_PROJECT_VERSION = 1;
413 | GENERATE_INFOPLIST_FILE = YES;
414 | MARKETING_VERSION = 1.0;
415 | PRODUCT_BUNDLE_IDENTIFIER = com.example.gputest.RunnerTests;
416 | PRODUCT_NAME = "$(TARGET_NAME)";
417 | SWIFT_VERSION = 5.0;
418 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gputest.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gputest";
419 | };
420 | name = Profile;
421 | };
422 | 338D0CE9231458BD00FA5F75 /* Profile */ = {
423 | isa = XCBuildConfiguration;
424 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
425 | buildSettings = {
426 | ALWAYS_SEARCH_USER_PATHS = NO;
427 | CLANG_ANALYZER_NONNULL = YES;
428 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
429 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
430 | CLANG_CXX_LIBRARY = "libc++";
431 | CLANG_ENABLE_MODULES = YES;
432 | CLANG_ENABLE_OBJC_ARC = YES;
433 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
434 | CLANG_WARN_BOOL_CONVERSION = YES;
435 | CLANG_WARN_CONSTANT_CONVERSION = YES;
436 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
437 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
438 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
439 | CLANG_WARN_EMPTY_BODY = YES;
440 | CLANG_WARN_ENUM_CONVERSION = YES;
441 | CLANG_WARN_INFINITE_RECURSION = YES;
442 | CLANG_WARN_INT_CONVERSION = YES;
443 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
444 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
445 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
446 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
447 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
448 | CODE_SIGN_IDENTITY = "-";
449 | COPY_PHASE_STRIP = NO;
450 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
451 | ENABLE_NS_ASSERTIONS = NO;
452 | ENABLE_STRICT_OBJC_MSGSEND = YES;
453 | GCC_C_LANGUAGE_STANDARD = gnu11;
454 | GCC_NO_COMMON_BLOCKS = YES;
455 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
456 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
457 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
458 | GCC_WARN_UNUSED_FUNCTION = YES;
459 | GCC_WARN_UNUSED_VARIABLE = YES;
460 | MACOSX_DEPLOYMENT_TARGET = 10.14;
461 | MTL_ENABLE_DEBUG_INFO = NO;
462 | SDKROOT = macosx;
463 | SWIFT_COMPILATION_MODE = wholemodule;
464 | SWIFT_OPTIMIZATION_LEVEL = "-O";
465 | };
466 | name = Profile;
467 | };
468 | 338D0CEA231458BD00FA5F75 /* Profile */ = {
469 | isa = XCBuildConfiguration;
470 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
471 | buildSettings = {
472 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
473 | CLANG_ENABLE_MODULES = YES;
474 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
475 | CODE_SIGN_STYLE = Automatic;
476 | COMBINE_HIDPI_IMAGES = YES;
477 | INFOPLIST_FILE = Runner/Info.plist;
478 | LD_RUNPATH_SEARCH_PATHS = (
479 | "$(inherited)",
480 | "@executable_path/../Frameworks",
481 | );
482 | PROVISIONING_PROFILE_SPECIFIER = "";
483 | SWIFT_VERSION = 5.0;
484 | };
485 | name = Profile;
486 | };
487 | 338D0CEB231458BD00FA5F75 /* Profile */ = {
488 | isa = XCBuildConfiguration;
489 | buildSettings = {
490 | CODE_SIGN_STYLE = Manual;
491 | PRODUCT_NAME = "$(TARGET_NAME)";
492 | };
493 | name = Profile;
494 | };
495 | 33CC10F92044A3C60003C045 /* Debug */ = {
496 | isa = XCBuildConfiguration;
497 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
498 | buildSettings = {
499 | ALWAYS_SEARCH_USER_PATHS = NO;
500 | CLANG_ANALYZER_NONNULL = YES;
501 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
502 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
503 | CLANG_CXX_LIBRARY = "libc++";
504 | CLANG_ENABLE_MODULES = YES;
505 | CLANG_ENABLE_OBJC_ARC = YES;
506 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
507 | CLANG_WARN_BOOL_CONVERSION = YES;
508 | CLANG_WARN_CONSTANT_CONVERSION = YES;
509 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
510 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
511 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
512 | CLANG_WARN_EMPTY_BODY = YES;
513 | CLANG_WARN_ENUM_CONVERSION = YES;
514 | CLANG_WARN_INFINITE_RECURSION = YES;
515 | CLANG_WARN_INT_CONVERSION = YES;
516 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
517 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
518 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
519 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
520 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
521 | CODE_SIGN_IDENTITY = "-";
522 | COPY_PHASE_STRIP = NO;
523 | DEBUG_INFORMATION_FORMAT = dwarf;
524 | ENABLE_STRICT_OBJC_MSGSEND = YES;
525 | ENABLE_TESTABILITY = YES;
526 | GCC_C_LANGUAGE_STANDARD = gnu11;
527 | GCC_DYNAMIC_NO_PIC = NO;
528 | GCC_NO_COMMON_BLOCKS = YES;
529 | GCC_OPTIMIZATION_LEVEL = 0;
530 | GCC_PREPROCESSOR_DEFINITIONS = (
531 | "DEBUG=1",
532 | "$(inherited)",
533 | );
534 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
535 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
536 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
537 | GCC_WARN_UNUSED_FUNCTION = YES;
538 | GCC_WARN_UNUSED_VARIABLE = YES;
539 | MACOSX_DEPLOYMENT_TARGET = 10.14;
540 | MTL_ENABLE_DEBUG_INFO = YES;
541 | ONLY_ACTIVE_ARCH = YES;
542 | SDKROOT = macosx;
543 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
544 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
545 | };
546 | name = Debug;
547 | };
548 | 33CC10FA2044A3C60003C045 /* Release */ = {
549 | isa = XCBuildConfiguration;
550 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
551 | buildSettings = {
552 | ALWAYS_SEARCH_USER_PATHS = NO;
553 | CLANG_ANALYZER_NONNULL = YES;
554 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
555 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
556 | CLANG_CXX_LIBRARY = "libc++";
557 | CLANG_ENABLE_MODULES = YES;
558 | CLANG_ENABLE_OBJC_ARC = YES;
559 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
560 | CLANG_WARN_BOOL_CONVERSION = YES;
561 | CLANG_WARN_CONSTANT_CONVERSION = YES;
562 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
563 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
564 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
565 | CLANG_WARN_EMPTY_BODY = YES;
566 | CLANG_WARN_ENUM_CONVERSION = YES;
567 | CLANG_WARN_INFINITE_RECURSION = YES;
568 | CLANG_WARN_INT_CONVERSION = YES;
569 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
570 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
571 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
572 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
573 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
574 | CODE_SIGN_IDENTITY = "-";
575 | COPY_PHASE_STRIP = NO;
576 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
577 | ENABLE_NS_ASSERTIONS = NO;
578 | ENABLE_STRICT_OBJC_MSGSEND = YES;
579 | GCC_C_LANGUAGE_STANDARD = gnu11;
580 | GCC_NO_COMMON_BLOCKS = YES;
581 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
582 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
583 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
584 | GCC_WARN_UNUSED_FUNCTION = YES;
585 | GCC_WARN_UNUSED_VARIABLE = YES;
586 | MACOSX_DEPLOYMENT_TARGET = 10.14;
587 | MTL_ENABLE_DEBUG_INFO = NO;
588 | SDKROOT = macosx;
589 | SWIFT_COMPILATION_MODE = wholemodule;
590 | SWIFT_OPTIMIZATION_LEVEL = "-O";
591 | };
592 | name = Release;
593 | };
594 | 33CC10FC2044A3C60003C045 /* Debug */ = {
595 | isa = XCBuildConfiguration;
596 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
597 | buildSettings = {
598 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
599 | CLANG_ENABLE_MODULES = YES;
600 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements;
601 | CODE_SIGN_STYLE = Automatic;
602 | COMBINE_HIDPI_IMAGES = YES;
603 | INFOPLIST_FILE = Runner/Info.plist;
604 | LD_RUNPATH_SEARCH_PATHS = (
605 | "$(inherited)",
606 | "@executable_path/../Frameworks",
607 | );
608 | PROVISIONING_PROFILE_SPECIFIER = "";
609 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
610 | SWIFT_VERSION = 5.0;
611 | };
612 | name = Debug;
613 | };
614 | 33CC10FD2044A3C60003C045 /* Release */ = {
615 | isa = XCBuildConfiguration;
616 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */;
617 | buildSettings = {
618 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
619 | CLANG_ENABLE_MODULES = YES;
620 | CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements;
621 | CODE_SIGN_STYLE = Automatic;
622 | COMBINE_HIDPI_IMAGES = YES;
623 | INFOPLIST_FILE = Runner/Info.plist;
624 | LD_RUNPATH_SEARCH_PATHS = (
625 | "$(inherited)",
626 | "@executable_path/../Frameworks",
627 | );
628 | PROVISIONING_PROFILE_SPECIFIER = "";
629 | SWIFT_VERSION = 5.0;
630 | };
631 | name = Release;
632 | };
633 | 33CC111C2044C6BA0003C045 /* Debug */ = {
634 | isa = XCBuildConfiguration;
635 | buildSettings = {
636 | CODE_SIGN_STYLE = Manual;
637 | PRODUCT_NAME = "$(TARGET_NAME)";
638 | };
639 | name = Debug;
640 | };
641 | 33CC111D2044C6BA0003C045 /* Release */ = {
642 | isa = XCBuildConfiguration;
643 | buildSettings = {
644 | CODE_SIGN_STYLE = Automatic;
645 | PRODUCT_NAME = "$(TARGET_NAME)";
646 | };
647 | name = Release;
648 | };
649 | /* End XCBuildConfiguration section */
650 |
651 | /* Begin XCConfigurationList section */
652 | 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
653 | isa = XCConfigurationList;
654 | buildConfigurations = (
655 | 331C80DB294CF71000263BE5 /* Debug */,
656 | 331C80DC294CF71000263BE5 /* Release */,
657 | 331C80DD294CF71000263BE5 /* Profile */,
658 | );
659 | defaultConfigurationIsVisible = 0;
660 | defaultConfigurationName = Release;
661 | };
662 | 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = {
663 | isa = XCConfigurationList;
664 | buildConfigurations = (
665 | 33CC10F92044A3C60003C045 /* Debug */,
666 | 33CC10FA2044A3C60003C045 /* Release */,
667 | 338D0CE9231458BD00FA5F75 /* Profile */,
668 | );
669 | defaultConfigurationIsVisible = 0;
670 | defaultConfigurationName = Release;
671 | };
672 | 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = {
673 | isa = XCConfigurationList;
674 | buildConfigurations = (
675 | 33CC10FC2044A3C60003C045 /* Debug */,
676 | 33CC10FD2044A3C60003C045 /* Release */,
677 | 338D0CEA231458BD00FA5F75 /* Profile */,
678 | );
679 | defaultConfigurationIsVisible = 0;
680 | defaultConfigurationName = Release;
681 | };
682 | 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = {
683 | isa = XCConfigurationList;
684 | buildConfigurations = (
685 | 33CC111C2044C6BA0003C045 /* Debug */,
686 | 33CC111D2044C6BA0003C045 /* Release */,
687 | 338D0CEB231458BD00FA5F75 /* Profile */,
688 | );
689 | defaultConfigurationIsVisible = 0;
690 | defaultConfigurationName = Release;
691 | };
692 | /* End XCConfigurationList section */
693 | };
694 | rootObject = 33CC10E52044A3C60003C045 /* Project object */;
695 | }
696 |
--------------------------------------------------------------------------------