From 72fec0020142152198851f4ecc42191cbb18d6d8 Mon Sep 17 00:00:00 2001 From: Brett Morgan Date: Sun, 2 Feb 2025 13:49:58 +1100 Subject: [PATCH 1/2] Fixup `intro_flutter_gpu` --- intro_flutter_gpu/codelab_rebuild.yaml | 69 ++++++++----------- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_01/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_01/lib/main.dart | 6 -- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_02/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_02/lib/main.dart | 6 -- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_03/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_03/lib/main.dart | 6 -- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_04/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_04/lib/main.dart | 6 -- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_05/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_05/lib/main.dart | 6 -- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_06/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_06/lib/main.dart | 6 -- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_07/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_07/lib/main.dart | 10 --- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_08/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_08/lib/main.dart | 10 --- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_09/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_09/lib/main.dart | 10 --- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_10/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_10/lib/main.dart | 10 --- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_11/android/settings.gradle.kts | 4 +- intro_flutter_gpu/step_11/lib/main.dart | 10 --- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../step_12/android/settings.gradle.kts | 4 +- 36 files changed, 63 insertions(+), 164 deletions(-) diff --git a/intro_flutter_gpu/codelab_rebuild.yaml b/intro_flutter_gpu/codelab_rebuild.yaml index d65f38fb3c..fe126cbc8e 100644 --- a/intro_flutter_gpu/codelab_rebuild.yaml +++ b/intro_flutter_gpu/codelab_rebuild.yaml @@ -137,9 +137,6 @@ steps: size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } // Create a render target for the texture final renderTarget = gpu.RenderTarget.singleColor( @@ -172,9 +169,6 @@ steps: final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } // Bind the pipeline and vertex buffer renderPass.bindPipeline(pipeline); @@ -337,7 +331,7 @@ steps: patch-u: | --- b/intro_flutter_gpu/step_02/lib/main.dart +++ a/intro_flutter_gpu/step_02/lib/main.dart - @@ -33,7 +33,6 @@ class TrianglePainter extends CustomPainter { + @@ -33,23 +33,19 @@ class TrianglePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { @@ -345,9 +339,8 @@ steps: final texture = gpu.gpuContext.createTexture( gpu.StorageMode.devicePrivate, size.width.ceil(), - @@ -43,16 +42,13 @@ class TrianglePainter extends CustomPainter { - throw Exception('Failed to create texture'); - } + size.height.ceil(), + ); - // Create a render target for the texture final renderTarget = gpu.RenderTarget.singleColor( @@ -362,7 +355,7 @@ steps: final vert = shaderLibrary['SimpleVertex']; if (vert == null) { throw Exception('Failed to load SimpleVertex vertex shader'); - @@ -63,14 +59,16 @@ class TrianglePainter extends CustomPainter { + @@ -60,19 +56,20 @@ class TrianglePainter extends CustomPainter { throw Exception('Failed to load SimpleFragment fragment shader'); } @@ -384,15 +377,12 @@ steps: final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - @@ -78,7 +76,6 @@ class TrianglePainter extends CustomPainter { - throw Exception('Failed to create vertices device buffer'); - } - // Bind the pipeline and vertex buffer renderPass.bindPipeline(pipeline); final verticesView = gpu.BufferView( - @@ -91,10 +88,8 @@ class TrianglePainter extends CustomPainter { + @@ -85,10 +82,8 @@ class TrianglePainter extends CustomPainter { vertices.length ~/ floatsPerVertex, ); @@ -451,7 +441,7 @@ steps: patch-u: | --- b/intro_flutter_gpu/step_03/lib/main.dart +++ a/intro_flutter_gpu/step_03/lib/main.dart - @@ -61,12 +61,18 @@ class TrianglePainter extends CustomPainter { + @@ -58,12 +58,18 @@ class TrianglePainter extends CustomPainter { final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); @@ -486,7 +476,7 @@ steps: patch-u: | --- b/intro_flutter_gpu/step_04/lib/main.dart +++ a/intro_flutter_gpu/step_04/lib/main.dart - @@ -66,13 +66,13 @@ class TrianglePainter extends CustomPainter { + @@ -63,13 +63,13 @@ class TrianglePainter extends CustomPainter { // Format: x, y, r, g, b // Triangle #1 @@ -520,7 +510,7 @@ steps: patch-u: | --- b/intro_flutter_gpu/step_05/lib/main.dart +++ a/intro_flutter_gpu/step_05/lib/main.dart - @@ -61,18 +61,18 @@ class TrianglePainter extends CustomPainter { + @@ -58,18 +58,18 @@ class TrianglePainter extends CustomPainter { final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); @@ -606,7 +596,7 @@ steps: patch-u: | --- b/intro_flutter_gpu/step_06/lib/main.dart +++ a/intro_flutter_gpu/step_06/lib/main.dart - @@ -61,18 +61,18 @@ class TrianglePainter extends CustomPainter { + @@ -58,18 +58,18 @@ class TrianglePainter extends CustomPainter { final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); @@ -760,7 +750,7 @@ steps: @override void paint(Canvas canvas, Size size) { - @@ -61,15 +98,12 @@ class TrianglePainter extends CustomPainter { + @@ -58,15 +95,12 @@ class TrianglePainter extends CustomPainter { final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); @@ -777,9 +767,9 @@ steps: 0.8, -0.8, 1.0, -1.0, 0.8, 0.8, 1.0, 1.0, -0.8, 0.8, -1.0, 1.0, - @@ -82,6 +116,22 @@ class TrianglePainter extends CustomPainter { - throw Exception('Failed to create vertices device buffer'); - } + @@ -76,6 +110,18 @@ class TrianglePainter extends CustomPainter { + ByteData.sublistView(vertices), + ); + // Create model matrix for rotation + final model = vm.Matrix4.rotationY(angle); @@ -792,15 +782,11 @@ steps: + Float32List.fromList(vertUniforms.expand((m) => m.storage).toList()), + ), + ); - + - + if (vertUniformsDeviceBuffer == null) { - + throw Exception('Failed to create vert uniforms device buffer'); - + } + renderPass.bindPipeline(pipeline); final verticesView = gpu.BufferView( - @@ -94,6 +144,14 @@ class TrianglePainter extends CustomPainter { + @@ -88,6 +134,14 @@ class TrianglePainter extends CustomPainter { vertices.length ~/ floatsPerVertex, ); @@ -860,9 +846,9 @@ steps: patch-u: | --- b/intro_flutter_gpu/step_08/lib/main.dart +++ a/intro_flutter_gpu/step_08/lib/main.dart - @@ -116,11 +116,18 @@ class TrianglePainter extends CustomPainter { - throw Exception('Failed to create vertices device buffer'); - } + @@ -110,11 +110,18 @@ class TrianglePainter extends CustomPainter { + ByteData.sublistView(vertices), + ); - // Create model matrix for rotation + // Create transformation matrices @@ -914,7 +900,7 @@ steps: patch-u: | --- b/intro_flutter_gpu/step_09/lib/main.dart +++ a/intro_flutter_gpu/step_09/lib/main.dart - @@ -98,15 +98,57 @@ class TrianglePainter extends CustomPainter { + @@ -95,22 +95,63 @@ class TrianglePainter extends CustomPainter { final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); @@ -980,15 +966,14 @@ steps: ]); final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( - @@ -116,7 +158,6 @@ class TrianglePainter extends CustomPainter { - throw Exception('Failed to create vertices device buffer'); - } + ByteData.sublistView(vertices), + ); - // Create transformation matrices final model = vm.Matrix4.rotationY(angle); final view = vm.Matrix4.translation(vm.Vector3(0.0, 0.0, -2.0)); final projection = vm.makePerspectiveMatrix( - @@ -126,7 +167,6 @@ class TrianglePainter extends CustomPainter { + @@ -120,7 +161,6 @@ class TrianglePainter extends CustomPainter { 100.0, ); @@ -1076,7 +1061,7 @@ steps: patch-u: | --- b/intro_flutter_gpu/step_10/lib/main.dart +++ a/intro_flutter_gpu/step_10/lib/main.dart - @@ -98,7 +98,7 @@ class TrianglePainter extends CustomPainter { + @@ -95,7 +95,7 @@ class TrianglePainter extends CustomPainter { final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); @@ -1085,7 +1070,7 @@ steps: final vertices = Float32List.fromList([ // Format: x, y, z, r, g, b - @@ -181,6 +181,9 @@ class TrianglePainter extends CustomPainter { + @@ -171,6 +171,9 @@ class TrianglePainter extends CustomPainter { renderPass.bindPipeline(pipeline); @@ -1123,9 +1108,9 @@ steps: } @override - @@ -158,8 +158,15 @@ class TrianglePainter extends CustomPainter { - throw Exception('Failed to create vertices device buffer'); - } + @@ -152,8 +152,15 @@ class TrianglePainter extends CustomPainter { + ByteData.sublistView(vertices), + ); - final model = vm.Matrix4.rotationY(angle); - final view = vm.Matrix4.translation(vm.Vector3(0.0, 0.0, -2.0)); @@ -1141,7 +1126,7 @@ steps: final projection = vm.makePerspectiveMatrix( vm.radians(45), size.aspectRatio, - @@ -181,7 +188,6 @@ class TrianglePainter extends CustomPainter { + @@ -171,7 +178,6 @@ class TrianglePainter extends CustomPainter { renderPass.bindPipeline(pipeline); diff --git a/intro_flutter_gpu/step_01/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_01/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_01/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_01/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_01/android/settings.gradle.kts b/intro_flutter_gpu/step_01/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_01/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_01/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_01/lib/main.dart b/intro_flutter_gpu/step_01/lib/main.dart index 82b01092e6..4d0da2ac3f 100644 --- a/intro_flutter_gpu/step_01/lib/main.dart +++ b/intro_flutter_gpu/step_01/lib/main.dart @@ -39,9 +39,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } // Create a render target for the texture final renderTarget = gpu.RenderTarget.singleColor( @@ -74,9 +71,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } // Bind the pipeline and vertex buffer renderPass.bindPipeline(pipeline); diff --git a/intro_flutter_gpu/step_02/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_02/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_02/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_02/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_02/android/settings.gradle.kts b/intro_flutter_gpu/step_02/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_02/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_02/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_02/lib/main.dart b/intro_flutter_gpu/step_02/lib/main.dart index d489ab776a..43a6d24a83 100644 --- a/intro_flutter_gpu/step_02/lib/main.dart +++ b/intro_flutter_gpu/step_02/lib/main.dart @@ -38,9 +38,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -72,9 +69,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } renderPass.bindPipeline(pipeline); diff --git a/intro_flutter_gpu/step_03/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_03/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_03/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_03/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_03/android/settings.gradle.kts b/intro_flutter_gpu/step_03/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_03/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_03/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_03/lib/main.dart b/intro_flutter_gpu/step_03/lib/main.dart index d4c617e1dc..ff331c7fe9 100644 --- a/intro_flutter_gpu/step_03/lib/main.dart +++ b/intro_flutter_gpu/step_03/lib/main.dart @@ -38,9 +38,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -78,9 +75,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } renderPass.bindPipeline(pipeline); diff --git a/intro_flutter_gpu/step_04/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_04/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_04/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_04/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_04/android/settings.gradle.kts b/intro_flutter_gpu/step_04/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_04/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_04/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_04/lib/main.dart b/intro_flutter_gpu/step_04/lib/main.dart index b68b0512da..556e45fc8d 100644 --- a/intro_flutter_gpu/step_04/lib/main.dart +++ b/intro_flutter_gpu/step_04/lib/main.dart @@ -38,9 +38,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -78,9 +75,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } renderPass.bindPipeline(pipeline); diff --git a/intro_flutter_gpu/step_05/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_05/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_05/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_05/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_05/android/settings.gradle.kts b/intro_flutter_gpu/step_05/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_05/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_05/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_05/lib/main.dart b/intro_flutter_gpu/step_05/lib/main.dart index 8d5e97253d..951734cd14 100644 --- a/intro_flutter_gpu/step_05/lib/main.dart +++ b/intro_flutter_gpu/step_05/lib/main.dart @@ -38,9 +38,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -78,9 +75,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } renderPass.bindPipeline(pipeline); diff --git a/intro_flutter_gpu/step_06/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_06/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_06/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_06/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_06/android/settings.gradle.kts b/intro_flutter_gpu/step_06/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_06/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_06/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_06/lib/main.dart b/intro_flutter_gpu/step_06/lib/main.dart index b4ba6992a1..a433ebd79c 100644 --- a/intro_flutter_gpu/step_06/lib/main.dart +++ b/intro_flutter_gpu/step_06/lib/main.dart @@ -38,9 +38,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -78,9 +75,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } renderPass.bindPipeline(pipeline); diff --git a/intro_flutter_gpu/step_07/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_07/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_07/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_07/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_07/android/settings.gradle.kts b/intro_flutter_gpu/step_07/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_07/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_07/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_07/lib/main.dart b/intro_flutter_gpu/step_07/lib/main.dart index afe9f0da0b..ce99cf44de 100644 --- a/intro_flutter_gpu/step_07/lib/main.dart +++ b/intro_flutter_gpu/step_07/lib/main.dart @@ -75,9 +75,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -112,9 +109,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } // Create model matrix for rotation final model = vm.Matrix4.rotationY(angle); @@ -128,10 +122,6 @@ class TrianglePainter extends CustomPainter { ), ); - if (vertUniformsDeviceBuffer == null) { - throw Exception('Failed to create vert uniforms device buffer'); - } - renderPass.bindPipeline(pipeline); final verticesView = gpu.BufferView( diff --git a/intro_flutter_gpu/step_08/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_08/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_08/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_08/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_08/android/settings.gradle.kts b/intro_flutter_gpu/step_08/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_08/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_08/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_08/lib/main.dart b/intro_flutter_gpu/step_08/lib/main.dart index 78ea9a9c75..3f770b89f1 100644 --- a/intro_flutter_gpu/step_08/lib/main.dart +++ b/intro_flutter_gpu/step_08/lib/main.dart @@ -75,9 +75,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -112,9 +109,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } // Create transformation matrices final model = vm.Matrix4.rotationY(angle); @@ -135,10 +129,6 @@ class TrianglePainter extends CustomPainter { ), ); - if (vertUniformsDeviceBuffer == null) { - throw Exception('Failed to create vert uniforms device buffer'); - } - renderPass.bindPipeline(pipeline); final verticesView = gpu.BufferView( diff --git a/intro_flutter_gpu/step_09/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_09/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_09/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_09/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_09/android/settings.gradle.kts b/intro_flutter_gpu/step_09/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_09/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_09/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_09/lib/main.dart b/intro_flutter_gpu/step_09/lib/main.dart index 68b90e23a7..bb609df3ae 100644 --- a/intro_flutter_gpu/step_09/lib/main.dart +++ b/intro_flutter_gpu/step_09/lib/main.dart @@ -75,9 +75,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -154,9 +151,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } final model = vm.Matrix4.rotationY(angle); final view = vm.Matrix4.translation(vm.Vector3(0.0, 0.0, -2.0)); @@ -175,10 +169,6 @@ class TrianglePainter extends CustomPainter { ), ); - if (vertUniformsDeviceBuffer == null) { - throw Exception('Failed to create vert uniforms device buffer'); - } - renderPass.bindPipeline(pipeline); final verticesView = gpu.BufferView( diff --git a/intro_flutter_gpu/step_10/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_10/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_10/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_10/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_10/android/settings.gradle.kts b/intro_flutter_gpu/step_10/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_10/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_10/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_10/lib/main.dart b/intro_flutter_gpu/step_10/lib/main.dart index f8c0a7d903..63830c17c7 100644 --- a/intro_flutter_gpu/step_10/lib/main.dart +++ b/intro_flutter_gpu/step_10/lib/main.dart @@ -75,9 +75,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -154,9 +151,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } final model = vm.Matrix4.rotationY(angle); final view = vm.Matrix4.translation(vm.Vector3(0.0, 0.0, -2.0)); @@ -175,10 +169,6 @@ class TrianglePainter extends CustomPainter { ), ); - if (vertUniformsDeviceBuffer == null) { - throw Exception('Failed to create vert uniforms device buffer'); - } - renderPass.bindPipeline(pipeline); // Add back-face culling diff --git a/intro_flutter_gpu/step_11/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_11/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_11/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_11/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_11/android/settings.gradle.kts b/intro_flutter_gpu/step_11/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_11/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_11/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/intro_flutter_gpu/step_11/lib/main.dart b/intro_flutter_gpu/step_11/lib/main.dart index a866ccaed3..ada20eb4f4 100644 --- a/intro_flutter_gpu/step_11/lib/main.dart +++ b/intro_flutter_gpu/step_11/lib/main.dart @@ -75,9 +75,6 @@ class TrianglePainter extends CustomPainter { size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), @@ -154,9 +151,6 @@ class TrianglePainter extends CustomPainter { final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } // Create model matrix with multiple rotations final model = @@ -182,10 +176,6 @@ class TrianglePainter extends CustomPainter { ), ); - if (vertUniformsDeviceBuffer == null) { - throw Exception('Failed to create vert uniforms device buffer'); - } - renderPass.bindPipeline(pipeline); renderPass.setCullMode(gpu.CullMode.backFace); diff --git a/intro_flutter_gpu/step_12/android/gradle/wrapper/gradle-wrapper.properties b/intro_flutter_gpu/step_12/android/gradle/wrapper/gradle-wrapper.properties index afa1e8eb0a..ac3b47926e 100644 --- a/intro_flutter_gpu/step_12/android/gradle/wrapper/gradle-wrapper.properties +++ b/intro_flutter_gpu/step_12/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/intro_flutter_gpu/step_12/android/settings.gradle.kts b/intro_flutter_gpu/step_12/android/settings.gradle.kts index a439442c20..ab39a10a29 100644 --- a/intro_flutter_gpu/step_12/android/settings.gradle.kts +++ b/intro_flutter_gpu/step_12/android/settings.gradle.kts @@ -18,8 +18,8 @@ pluginManagement { plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.7.0" apply false - id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") From 410b2255603e662f9e448c5707f7da92752ccfe6 Mon Sep 17 00:00:00 2001 From: Brett Morgan Date: Mon, 3 Feb 2025 05:15:20 +1100 Subject: [PATCH 2/2] Update prompt --- intro_flutter_gpu/prompt.md | 533 ++++++++++++++++++++++-------------- 1 file changed, 320 insertions(+), 213 deletions(-) diff --git a/intro_flutter_gpu/prompt.md b/intro_flutter_gpu/prompt.md index 216aaf0d1c..b2cabf0874 100644 --- a/intro_flutter_gpu/prompt.md +++ b/intro_flutter_gpu/prompt.md @@ -5,7 +5,7 @@ Flutter GPU APIs exposed in Flutter's Impeller on Android, iOS, Windows, macOS a The codelab is called "Introduction to Flutter GPU". The codelab is made up of a series of steps. -This codelab requires Flutter version 3.28, which comes with Dart 3.7. +This codelab requires Flutter version 3.30, which comes with Dart 3.8. ## Step 1. Single Green Triange @@ -56,7 +56,7 @@ publish_to: 'none' version: 0.1.0 environment: - sdk: ^3.7.0 + sdk: ^3.8.0 dependencies: flutter: @@ -196,22 +196,23 @@ class TrianglePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { + // Create a texture to render to final texture = gpu.gpuContext.createTexture( gpu.StorageMode.devicePrivate, size.width.ceil(), size.height.ceil(), ); - if (texture == null) { - throw Exception('Failed to create texture'); - } + // Create a render target for the texture final renderTarget = gpu.RenderTarget.singleColor( gpu.ColorAttachment(texture: texture), ); + // Create a command buffer and render pass final commandBuffer = gpu.gpuContext.createCommandBuffer(); final renderPass = commandBuffer.createRenderPass(renderTarget); + // Load our shaders final vert = shaderLibrary['SimpleVertex']; if (vert == null) { throw Exception('Failed to load SimpleVertex vertex shader'); @@ -222,22 +223,19 @@ class TrianglePainter extends CustomPainter { throw Exception('Failed to load SimpleFragment fragment shader'); } + // Create the rendering pipeline final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); + // Define our triangle vertices const floatsPerVertex = 2; - final vertices = Float32List.fromList([ - -0.5, -0.5, // First vertex - 0.5, -0.5, // Second vertex - 0.0, 0.5, // Third vertex - ]); + final vertices = Float32List.fromList([-0.5, -0.5, 0.5, -0.5, 0.0, 0.5]); + // Create a GPU buffer for our vertices final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ByteData.sublistView(vertices), ); - if (verticesDeviceBuffer == null) { - throw Exception('Failed to create vertices device buffer'); - } + // Bind the pipeline and vertex buffer renderPass.bindPipeline(pipeline); final verticesView = gpu.BufferView( @@ -250,8 +248,10 @@ class TrianglePainter extends CustomPainter { vertices.length ~/ floatsPerVertex, ); + // Draw the triangle renderPass.draw(); + // Submit commands to GPU and render to screen commandBuffer.submit(); final image = texture.asImage(); canvas.drawImage(image, Offset.zero, Paint()); @@ -274,23 +274,68 @@ Modify `lib/main.dart` as follows ```diff --- b/intro_flutter_gpu/step_02/lib/main.dart +++ a/intro_flutter_gpu/step_02/lib/main.dart -@@ -61,11 +61,12 @@ class TrianglePainter extends CustomPainter { - - final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); - +@@ -33,23 +33,19 @@ class TrianglePainter extends CustomPainter { + + @override + void paint(Canvas canvas, Size size) { +- // Create a texture to render to + final texture = gpu.gpuContext.createTexture( + gpu.StorageMode.devicePrivate, + size.width.ceil(), + size.height.ceil(), + ); + +- // Create a render target for the texture + final renderTarget = gpu.RenderTarget.singleColor( + gpu.ColorAttachment(texture: texture), + ); + +- // Create a command buffer and render pass + final commandBuffer = gpu.gpuContext.createCommandBuffer(); + final renderPass = commandBuffer.createRenderPass(renderTarget); + +- // Load our shaders + final vert = shaderLibrary['SimpleVertex']; + if (vert == null) { + throw Exception('Failed to load SimpleVertex vertex shader'); +@@ -60,19 +56,20 @@ class TrianglePainter extends CustomPainter { + throw Exception('Failed to load SimpleFragment fragment shader'); + } + +- // Create the rendering pipeline + final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); + +- // Define our triangle vertices - const floatsPerVertex = 2; -+ const floatsPerVertex = 5; - final vertices = Float32List.fromList([ -- -0.5, -0.5, // First vertex -- 0.5, -0.5, // Second vertex -- 0.0, 0.5, // Third vertex -+ // Format: x, y, r, g, b, +- final vertices = Float32List.fromList([-0.5, -0.5, 0.5, -0.5, 0.0, 0.5]); ++ const floatsPerVertex = 5; // Now 2 for position + 3 for color ++ final vertices = Float32List.fromList([ ++ // Format: x, y, r, g, b + -0.5, -0.5, 1.0, 0.0, 0.0, + 0.5, -0.5, 0.0, 1.0, 0.0, + 0.0, 0.5, 0.0, 0.0, 1.0, - ]); - - final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ++ ]); + +- // Create a GPU buffer for our vertices + final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( + ByteData.sublistView(vertices), + ); + +- // Bind the pipeline and vertex buffer + renderPass.bindPipeline(pipeline); + + final verticesView = gpu.BufferView( +@@ -85,10 +82,8 @@ class TrianglePainter extends CustomPainter { + vertices.length ~/ floatsPerVertex, + ); + +- // Draw the triangle + renderPass.draw(); + +- // Submit commands to GPU and render to screen + commandBuffer.submit(); + final image = texture.asImage(); + canvas.drawImage(image, Offset.zero, Paint()); ``` Update `shaders/simple.vert` as follows @@ -339,25 +384,27 @@ Update `lib/main.dart` as follows ```diff --- b/intro_flutter_gpu/step_03/lib/main.dart +++ a/intro_flutter_gpu/step_03/lib/main.dart -@@ -64,9 +64,15 @@ class TrianglePainter extends CustomPainter { - const floatsPerVertex = 5; - final vertices = Float32List.fromList([ - // Format: x, y, r, g, b, -- -0.5, -0.5, 1.0, 0.0, 0.0, -- 0.5, -0.5, 0.0, 1.0, 0.0, -- 0.0, 0.5, 0.0, 0.0, 1.0, +@@ -58,12 +58,18 @@ class TrianglePainter extends CustomPainter { + + final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); + +- const floatsPerVertex = 5; // Now 2 for position + 3 for color ++ const floatsPerVertex = 5; + final vertices = Float32List.fromList([ + // Format: x, y, r, g, b + -+ // Traingle #1 -+ -0.5, -0.5, 1.0, 0.0, 0.0, // bottom left -+ 0.5, -0.5, 0.0, 1.0, 0.0, // bottom right -+ -0.5, 0.5, 0.0, 0.0, 1.0, // top left -+ // Traingle #2 -+ 0.5, -0.5, 0.0, 1.0, 0.0, // bottom right -+ 0.5, 0.5, 1.0, 1.0, 0.0, // top right -+ -0.5, 0.5, 0.0, 0.0, 1.0, // top left - ]); - - final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ++ // Triangle #1 + -0.5, -0.5, 1.0, 0.0, 0.0, + 0.5, -0.5, 0.0, 1.0, 0.0, +- 0.0, 0.5, 0.0, 0.0, 1.0, ++ -0.5, 0.5, 0.0, 0.0, 1.0, ++ // Triangle #2 ++ 0.5, -0.5, 0.0, 1.0, 0.0, ++ 0.5, 0.5, 1.0, 1.0, 0.0, ++ -0.5, 0.5, 0.0, 0.0, 1.0, + ]); + + final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ``` ## Step 4. Two triangles with broken color interpolation @@ -367,26 +414,26 @@ Update `lib/main.dart` as follows ```diff --- b/intro_flutter_gpu/step_04/lib/main.dart +++ a/intro_flutter_gpu/step_04/lib/main.dart -@@ -66,13 +66,13 @@ class TrianglePainter extends CustomPainter { - // Format: x, y, r, g, b, - - // Traingle #1 -- -0.5, -0.5, 1.0, 0.0, 0.0, // bottom left -- 0.5, -0.5, 0.0, 1.0, 0.0, // bottom right -- -0.5, 0.5, 0.0, 0.0, 1.0, // top left -+ -0.5, -0.5, 0.0, 0.0, 1.0, // bottom left -+ 0.5, -0.5, 1.0, 1.0, 0.0, // bottom right -+ -0.5, 0.5, 1.0, 0.0, 0.0, // top left - // Traingle #2 -- 0.5, -0.5, 0.0, 1.0, 0.0, // bottom right -- 0.5, 0.5, 1.0, 1.0, 0.0, // top right -- -0.5, 0.5, 0.0, 0.0, 1.0, // top left -+ 0.5, -0.5, 1.0, 1.0, 0.0, // bottom right -+ 0.5, 0.5, 0.0, 1.0, 0.0, // top right -+ -0.5, 0.5, 1.0, 0.0, 0.0, // top left - ]); - - final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( +@@ -63,13 +63,13 @@ class TrianglePainter extends CustomPainter { + // Format: x, y, r, g, b + + // Triangle #1 +- -0.5, -0.5, 1.0, 0.0, 0.0, +- 0.5, -0.5, 0.0, 1.0, 0.0, +- -0.5, 0.5, 0.0, 0.0, 1.0, ++ -0.5, -0.5, 0.0, 0.0, 1.0, ++ 0.5, -0.5, 1.0, 1.0, 0.0, ++ -0.5, 0.5, 1.0, 0.0, 0.0, + // Triangle #2 +- 0.5, -0.5, 0.0, 1.0, 0.0, +- 0.5, 0.5, 1.0, 1.0, 0.0, +- -0.5, 0.5, 0.0, 0.0, 1.0, ++ 0.5, -0.5, 1.0, 1.0, 0.0, ++ 0.5, 0.5, 0.0, 1.0, 0.0, ++ -0.5, 0.5, 1.0, 0.0, 0.0, + ]); + + final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ``` ## Step 5. Introduce UV to fix color interpolation @@ -396,33 +443,33 @@ Update `lib/main.dart` as follows ```diff --- b/intro_flutter_gpu/step_05/lib/main.dart +++ a/intro_flutter_gpu/step_05/lib/main.dart -@@ -61,18 +61,18 @@ class TrianglePainter extends CustomPainter { - - final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); - +@@ -58,18 +58,18 @@ class TrianglePainter extends CustomPainter { + + final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); + - const floatsPerVertex = 5; -+ const floatsPerVertex = 4; - final vertices = Float32List.fromList([ -- // Format: x, y, r, g, b, -+ // Format: x, y, u, v, - - // Traingle #1 -- -0.5, -0.5, 0.0, 0.0, 1.0, // bottom left -- 0.5, -0.5, 1.0, 1.0, 0.0, // bottom right -- -0.5, 0.5, 1.0, 0.0, 0.0, // top left -+ -0.5, -0.5, 0.0, 0.0, // bottom left -+ 0.5, -0.5, 1.0, 0.0, // bottom right -+ -0.5, 0.5, 0.0, 1.0, // top left - // Traingle #2 -- 0.5, -0.5, 1.0, 1.0, 0.0, // bottom right -- 0.5, 0.5, 0.0, 1.0, 0.0, // top right -- -0.5, 0.5, 1.0, 0.0, 0.0, // top left -+ 0.5, -0.5, 1.0, 0.0, // bottom right -+ 0.5, 0.5, 1.0, 1.0, // top right -+ -0.5, 0.5, 0.0, 1.0, // top left - ]); - - final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ++ const floatsPerVertex = 4; // Now 2 for position + 2 for UV + final vertices = Float32List.fromList([ +- // Format: x, y, r, g, b ++ // Format: x, y, u, v + + // Triangle #1 +- -0.5, -0.5, 0.0, 0.0, 1.0, +- 0.5, -0.5, 1.0, 1.0, 0.0, +- -0.5, 0.5, 1.0, 0.0, 0.0, ++ -0.5, -0.5, 0.0, 0.0, ++ 0.5, -0.5, 1.0, 0.0, ++ -0.5, 0.5, 0.0, 1.0, + // Triangle #2 +- 0.5, -0.5, 1.0, 1.0, 0.0, +- 0.5, 0.5, 0.0, 1.0, 0.0, +- -0.5, 0.5, 1.0, 0.0, 0.0, ++ 0.5, -0.5, 1.0, 0.0, ++ 0.5, 0.5, 1.0, 1.0, ++ -0.5, 0.5, 0.0, 1.0, + ]); + + final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ``` Modify `shaders/simple.vert` as follows @@ -481,26 +528,32 @@ Update `lib/main.dart` as follows ```diff --- b/intro_flutter_gpu/step_06/lib/main.dart +++ a/intro_flutter_gpu/step_06/lib/main.dart -@@ -66,13 +66,13 @@ class TrianglePainter extends CustomPainter { - // Format: x, y, u, v, - - // Traingle #1 -- -0.5, -0.5, 0.0, 0.0, // bottom left -- 0.5, -0.5, 1.0, 0.0, // bottom right -- -0.5, 0.5, 0.0, 1.0, // top left -+ -0.8, -0.8, -1.0, -1.0, // bottom left -+ 0.8, -0.8, 1.0, -1.0, // bottom right -+ -0.8, 0.8, -1.0, 1.0, // top left - // Traingle #2 -- 0.5, -0.5, 1.0, 0.0, // bottom right -- 0.5, 0.5, 1.0, 1.0, // top right -- -0.5, 0.5, 0.0, 1.0, // top left -+ 0.8, -0.8, 1.0, -1.0, // bottom right -+ 0.8, 0.8, 1.0, 1.0, // top right -+ -0.8, 0.8, -1.0, 1.0, // top left - ]); - - final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( +@@ -58,18 +58,18 @@ class TrianglePainter extends CustomPainter { + + final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); + +- const floatsPerVertex = 4; // Now 2 for position + 2 for UV ++ const floatsPerVertex = 4; // 2 for position + 2 for UV + final vertices = Float32List.fromList([ + // Format: x, y, u, v + + // Triangle #1 +- -0.5, -0.5, 0.0, 0.0, +- 0.5, -0.5, 1.0, 0.0, +- -0.5, 0.5, 0.0, 1.0, ++ -0.8, -0.8, -1.0, -1.0, ++ 0.8, -0.8, 1.0, -1.0, ++ -0.8, 0.8, -1.0, 1.0, + // Triangle #2 +- 0.5, -0.5, 1.0, 0.0, +- 0.5, 0.5, 1.0, 1.0, +- -0.5, 0.5, 0.0, 1.0, ++ 0.8, -0.8, 1.0, -1.0, ++ 0.8, 0.8, 1.0, 1.0, ++ -0.8, 0.8, -1.0, 1.0, + ]); + + final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ``` Modify `shaders/simple.frag` as follows @@ -553,26 +606,26 @@ Update `lib/main.dart` as follows --- b/intro_flutter_gpu/step_07/lib/main.dart +++ a/intro_flutter_gpu/step_07/lib/main.dart @@ -2,10 +2,12 @@ - // Use of this source code is governed by a BSD-style license that can be - // found in the LICENSE file. - + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +import 'dart:math' as math; - import 'dart:typed_data'; - - import 'package:flutter/material.dart'; - import 'package:flutter_gpu/gpu.dart' as gpu; + import 'dart:typed_data'; + + import 'package:flutter/material.dart'; + import 'package:flutter_gpu/gpu.dart' as gpu; +import 'package:vector_math/vector_math.dart' as vm; - - import 'shaders.dart'; - + + import 'shaders.dart'; + @@ -13,23 +15,58 @@ void main() { - runApp(const MainApp()); - } - + runApp(const MainApp()); + } + -class MainApp extends StatelessWidget { +class MainApp extends StatefulWidget { - const MainApp({super.key}); - + const MainApp({super.key}); + + @override + State createState() => _MainAppState(); +} @@ -598,41 +651,60 @@ Update `lib/main.dart` as follows + super.dispose(); + } + - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter GPU Triangle Demo', - debugShowCheckedModeBanner: false, - home: Scaffold( + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter GPU Triangle Demo', + debugShowCheckedModeBanner: false, + home: Scaffold( - body: SizedBox.expand(child: CustomPaint(painter: TrianglePainter())), + body: SizedBox.expand( + child: AnimatedBuilder( ++ animation: _animation, + builder: (context, child) { + return CustomPaint( + painter: TrianglePainter(angle: _animation.value), + ); + }, -+ animation: _animation, + ), + ), - ), - ); - } - } - - class TrianglePainter extends CustomPainter { + ), + ); + } + } + + class TrianglePainter extends CustomPainter { - const TrianglePainter(); + const TrianglePainter({required this.angle}); + final double angle; - - @override - void paint(Canvas canvas, Size size) { -@@ -82,6 +119,20 @@ class TrianglePainter extends CustomPainter { - throw Exception('Failed to create vertices device buffer'); - } - + + @override + void paint(Canvas canvas, Size size) { +@@ -58,15 +95,12 @@ class TrianglePainter extends CustomPainter { + + final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); + +- const floatsPerVertex = 4; // 2 for position + 2 for UV ++ const floatsPerVertex = 4; + final vertices = Float32List.fromList([ + // Format: x, y, u, v +- +- // Triangle #1 + -0.8, -0.8, -1.0, -1.0, + 0.8, -0.8, 1.0, -1.0, + -0.8, 0.8, -1.0, 1.0, +- // Triangle #2 + 0.8, -0.8, 1.0, -1.0, + 0.8, 0.8, 1.0, 1.0, + -0.8, 0.8, -1.0, 1.0, +@@ -76,6 +110,18 @@ class TrianglePainter extends CustomPainter { + ByteData.sublistView(vertices), + ); + ++ // Create model matrix for rotation + final model = vm.Matrix4.rotationY(angle); + ++ // Create uniform buffer with transformation matrix + final vertUniforms = [model]; + + final vertUniformsDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( @@ -641,17 +713,13 @@ Update `lib/main.dart` as follows + ), + ); + -+ if (vertUniformsDeviceBuffer == null) { -+ throw Exception('Failed to create vert uniforms device buffer'); -+ } -+ - renderPass.bindPipeline(pipeline); - - final verticesView = gpu.BufferView( -@@ -94,6 +145,14 @@ class TrianglePainter extends CustomPainter { - vertices.length ~/ floatsPerVertex, - ); - + renderPass.bindPipeline(pipeline); + + final verticesView = gpu.BufferView( +@@ -88,6 +134,14 @@ class TrianglePainter extends CustomPainter { + vertices.length ~/ floatsPerVertex, + ); + + final vertUniformsView = gpu.BufferView( + vertUniformsDeviceBuffer, + offsetInBytes: 0, @@ -660,9 +728,9 @@ Update `lib/main.dart` as follows + + renderPass.bindUniform(vert.getUniformSlot('VertInfo'), vertUniformsView); + - renderPass.draw(); - - commandBuffer.submit(); + renderPass.draw(); + + commandBuffer.submit(); ``` Modify `shaders/simple.vert` as follows @@ -692,23 +760,28 @@ Update `lib/main.dart` as follows ```diff --- b/intro_flutter_gpu/step_08/lib/main.dart +++ a/intro_flutter_gpu/step_08/lib/main.dart -@@ -120,8 +120,15 @@ class TrianglePainter extends CustomPainter { - } - - final model = vm.Matrix4.rotationY(angle); +@@ -110,11 +110,18 @@ class TrianglePainter extends CustomPainter { + ByteData.sublistView(vertices), + ); + +- // Create model matrix for rotation ++ // Create transformation matrices + final model = vm.Matrix4.rotationY(angle); + final view = vm.Matrix4.translation(vm.Vector3(0.0, 0.0, -2.0)); + final projection = vm.makePerspectiveMatrix( + vm.radians(45), + size.aspectRatio, + 0.1, -+ 100, ++ 100.0, + ); - + +- // Create uniform buffer with transformation matrix - final vertUniforms = [model]; ++ // Pack matrices into uniform buffer + final vertUniforms = [model, view, projection]; - - final vertUniformsDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( - ByteData.sublistView( + + final vertUniformsDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( + ByteData.sublistView( ``` Modify `shaders/simple.vert` as follows @@ -738,24 +811,21 @@ Update `lib/main.dart` as follows ```diff --- b/intro_flutter_gpu/step_09/lib/main.dart +++ a/intro_flutter_gpu/step_09/lib/main.dart -@@ -98,18 +98,57 @@ class TrianglePainter extends CustomPainter { - - final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); - +@@ -95,22 +95,63 @@ class TrianglePainter extends CustomPainter { + + final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); + - const floatsPerVertex = 4; -+ const floatsPerVertex = 6; - final vertices = Float32List.fromList([ -- // Format: x, y, u, v, -- -- // Traingle #1 -- -0.8, -0.8, -1.0, -1.0, // bottom left -- 0.8, -0.8, 1.0, -1.0, // bottom right -- -0.8, 0.8, -1.0, 1.0, // top left -- // Traingle #2 -- 0.8, -0.8, 1.0, -1.0, // bottom right -- 0.8, 0.8, 1.0, 1.0, // top right -- -0.8, 0.8, -1.0, 1.0, // top left -+ // layout: x, y, z, r, g, b ++ const floatsPerVertex = 6; // 3 for position + 3 for color + final vertices = Float32List.fromList([ +- // Format: x, y, u, v +- -0.8, -0.8, -1.0, -1.0, +- 0.8, -0.8, 1.0, -1.0, +- -0.8, 0.8, -1.0, 1.0, +- 0.8, -0.8, 1.0, -1.0, +- 0.8, 0.8, 1.0, 1.0, +- -0.8, 0.8, -1.0, 1.0, ++ // Format: x, y, z, r, g, b + + // Back Face + -0.5, -0.5, -0.5, 1.0, 0.0, 0.0, @@ -804,9 +874,24 @@ Update `lib/main.dart` as follows + 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, + -0.5, 0.5, 0.5, 1.0, 1.0, 0.0, + -0.5, 0.5, -0.5, 1.0, 0.0, 0.0, - ]); - - final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( + ]); + + final verticesDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( + ByteData.sublistView(vertices), + ); + +- // Create transformation matrices + final model = vm.Matrix4.rotationY(angle); + final view = vm.Matrix4.translation(vm.Vector3(0.0, 0.0, -2.0)); + final projection = vm.makePerspectiveMatrix( +@@ -120,7 +161,6 @@ class TrianglePainter extends CustomPainter { + 100.0, + ); + +- // Pack matrices into uniform buffer + final vertUniforms = [model, view, projection]; + + final vertUniformsDeviceBuffer = gpu.gpuContext.createDeviceBufferWithCopy( ``` Update `shaders/simple.frag` as follows @@ -888,15 +973,25 @@ Modify `lib/main.dart` as follows ```diff --- b/intro_flutter_gpu/step_10/lib/main.dart +++ a/intro_flutter_gpu/step_10/lib/main.dart -@@ -181,6 +181,8 @@ class TrianglePainter extends CustomPainter { - - renderPass.bindPipeline(pipeline); - +@@ -95,7 +95,7 @@ class TrianglePainter extends CustomPainter { + + final pipeline = gpu.gpuContext.createRenderPipeline(vert, frag); + +- const floatsPerVertex = 6; // 3 for position + 3 for color ++ const floatsPerVertex = 6; + final vertices = Float32List.fromList([ + // Format: x, y, z, r, g, b + +@@ -171,6 +171,9 @@ class TrianglePainter extends CustomPainter { + + renderPass.bindPipeline(pipeline); + ++ // Add back-face culling + renderPass.setCullMode(gpu.CullMode.backFace); + - final verticesView = gpu.BufferView( - verticesDeviceBuffer, - offsetInBytes: 0, + final verticesView = gpu.BufferView( + verticesDeviceBuffer, + offsetInBytes: 0, ``` ## Step 11. Rotating in two dimensions @@ -907,33 +1002,45 @@ Update `liob/main.dart` as follows --- b/intro_flutter_gpu/step_11/lib/main.dart +++ a/intro_flutter_gpu/step_11/lib/main.dart @@ -30,11 +30,11 @@ class _MainAppState extends State with SingleTickerProviderStateMixin { - void initState() { - super.initState(); - _controller = AnimationController( + void initState() { + super.initState(); + _controller = AnimationController( - duration: const Duration(seconds: 15), + duration: const Duration(seconds: 30), - vsync: this, - )..repeat(); - + vsync: this, + )..repeat(); + - _animation = Tween(begin: 0, end: 2 * math.pi).animate(_controller); + _animation = Tween(begin: 0, end: 4 * math.pi).animate(_controller); - } - - @override -@@ -158,8 +158,11 @@ class TrianglePainter extends CustomPainter { - throw Exception('Failed to create vertices device buffer'); - } - + } + + @override +@@ -152,8 +152,15 @@ class TrianglePainter extends CustomPainter { + ByteData.sublistView(vertices), + ); + - final model = vm.Matrix4.rotationY(angle); - final view = vm.Matrix4.translation(vm.Vector3(0.0, 0.0, -2.0)); ++ // Create model matrix with multiple rotations + final model = + vm.Matrix4.identity() + ..rotateY(angle) + ..rotateX(angle / 2); ++ ++ // Move camera back a bit more for better view + final view = vm.Matrix4.translation(vm.Vector3(0.0, 0.0, -2.5)); - final projection = vm.makePerspectiveMatrix( - vm.radians(45), - size.aspectRatio, ++ + final projection = vm.makePerspectiveMatrix( + vm.radians(45), + size.aspectRatio, +@@ -171,7 +178,6 @@ class TrianglePainter extends CustomPainter { + + renderPass.bindPipeline(pipeline); + +- // Add back-face culling + renderPass.setCullMode(gpu.CullMode.backFace); + + final verticesView = gpu.BufferView( ``` ## Step 12. Use Flutter Scene @@ -1178,7 +1285,7 @@ class ScenePainter extends CustomPainter { **4. Testing and Validation:** * The codelab code is tested under CI on Github.com -* This code requires Flutter version 3.28 to have the required APIs exposed from `flutter_gpu` +* This code requires Flutter version 3.30 to have the required APIs exposed from `flutter_gpu` * The code for this codelab will be hosted on github.com/flutter/codelabs with each step's code broken out separately **5. Content and Explanations:** @@ -1207,7 +1314,7 @@ Notes **Prerequisites:** -* Flutter SDK version 3.28 or later (includes Dart 3.7). +* Flutter SDK version 3.30 or later. * Basic understanding of Flutter development (Widgets, layouts, state management). * Familiarity with the command-line interface.