Add getUniformMatX support for desktop and mobile (#182117)
Adds getUniformMatX and getUniformMatXArray functions to desktop and
mobile.
Also fixes a padding issue with mat3s on Vulkan.
diff --git a/engine/src/flutter/impeller/compiler/reflector.cc b/engine/src/flutter/impeller/compiler/reflector.cc
index a506adf..eacc264 100644
--- a/engine/src/flutter/impeller/compiler/reflector.cc
+++ b/engine/src/flutter/impeller/compiler/reflector.cc
@@ -936,6 +936,29 @@
continue;
}
+ if (member.basetype == spirv_cross::SPIRType::BaseType::Float &&
+ member.width == 32 && member.columns == 3 && member.vecsize == 3) {
+ // Mat3s are packed as three vec3s with one float of padding after each.
+ // {val, val, val, padding, val, val, val, padding, val, val, val,
+ // padding}.
+ uint32_t count = array_elements.value_or(1) * 3;
+ uint32_t stride = 16;
+ uint32_t total_length = stride * count;
+
+ result.emplace_back(StructMember{
+ /*p_type=*/"Mat3",
+ /*p_base_type=*/spirv_cross::SPIRType::BaseType::Float,
+ /*p_name=*/GetMemberNameAtIndex(struct_type, i),
+ /*p_offset=*/struct_member_offset,
+ /*p_size=*/12,
+ /*p_byte_length=*/total_length,
+ /*p_array_elements=*/count,
+ /*p_element_padding=*/4,
+ });
+ current_byte_offset += total_length;
+ continue;
+ }
+
// Tightly packed 4x4 Matrix is special cased as we know how to work with
// those.
if (member.basetype == spirv_cross::SPIRType::BaseType::Float && //
diff --git a/engine/src/flutter/impeller/runtime_stage/runtime_stage_unittests.cc b/engine/src/flutter/impeller/runtime_stage/runtime_stage_unittests.cc
index ea47b44..36e7ad4 100644
--- a/engine/src/flutter/impeller/runtime_stage/runtime_stage_unittests.cc
+++ b/engine/src/flutter/impeller/runtime_stage/runtime_stage_unittests.cc
@@ -242,7 +242,7 @@
stage->GetUniform(RuntimeStage::kVulkanUBOName);
ASSERT_TRUE(uni);
EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
- EXPECT_EQ(uni->struct_float_count, 35u);
+ EXPECT_EQ(uni->struct_float_count, 26u);
EXPECT_EQ(uni->GetGPUSize(), 640u);
std::vector<RuntimePaddingType> layout(uni->GetGPUSize() / sizeof(float),
@@ -257,9 +257,9 @@
layout[15] = RuntimePaddingType::kPadding;
layout[18] = RuntimePaddingType::kPadding;
layout[19] = RuntimePaddingType::kPadding;
- // uMat3 is packed as 3 vec4s, with the last 3 bytes being padding
- layout[29] = RuntimePaddingType::kPadding;
- layout[30] = RuntimePaddingType::kPadding;
+ // uMat3 is packed as 3 vec4s, with the last byte of each being padding
+ layout[23] = RuntimePaddingType::kPadding;
+ layout[27] = RuntimePaddingType::kPadding;
layout[31] = RuntimePaddingType::kPadding;
// uFloatArray is packed as 2 vec4s, with the last 3 bytes of each
// being padding.
@@ -280,7 +280,7 @@
layout[71] = RuntimePaddingType::kPadding;
// uVec4Array has no padding.
// uMat2Array[2] is packed as 4 vec4s, With the last 2 bytes of each being
- // padding. padding.
+ // padding.
layout[82] = RuntimePaddingType::kPadding;
layout[83] = RuntimePaddingType::kPadding;
layout[86] = RuntimePaddingType::kPadding;
@@ -289,13 +289,13 @@
layout[91] = RuntimePaddingType::kPadding;
layout[94] = RuntimePaddingType::kPadding;
layout[95] = RuntimePaddingType::kPadding;
- // uMat3Array[2] is packed as 6 vec4s, with the last 3 bytes of the 3rd
- // and 6th being padding.
- layout[105] = RuntimePaddingType::kPadding;
- layout[106] = RuntimePaddingType::kPadding;
+ // uMat3Array[2] is packed as 6 vec4s, with the last byte of each being
+ // padding.
+ layout[99] = RuntimePaddingType::kPadding;
+ layout[103] = RuntimePaddingType::kPadding;
layout[107] = RuntimePaddingType::kPadding;
- layout[117] = RuntimePaddingType::kPadding;
- layout[118] = RuntimePaddingType::kPadding;
+ layout[111] = RuntimePaddingType::kPadding;
+ layout[115] = RuntimePaddingType::kPadding;
layout[119] = RuntimePaddingType::kPadding;
// uMat4Array[2] is packed as 8 vec4s with no padding.
layout[152] = RuntimePaddingType::kPadding;
diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/BUILD.gn b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/BUILD.gn
index d75abef..0268468 100644
--- a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/BUILD.gn
+++ b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/BUILD.gn
@@ -17,6 +17,12 @@
"vec3_array_uniform.frag",
"vec4_uniform.frag",
"vec4_array_uniform.frag",
+ "mat2_uniform.frag",
+ "mat2_array_uniform.frag",
+ "mat3_uniform.frag",
+ "mat3_array_uniform.frag",
+ "mat4_uniform.frag",
+ "mat4_array_uniform.frag",
]
group("uniforms") {
diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/all_uniforms.frag b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/all_uniforms.frag
index 2df139c..e5d3bcc 100644
--- a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/all_uniforms.frag
+++ b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/all_uniforms.frag
@@ -7,7 +7,7 @@
out vec4 fragColor;
// One for each base type, 40 for the arrays
-float N_COLOR_VALUES = 44;
+float N_COLOR_VALUES = 143;
uniform float uFloat;
@@ -15,6 +15,10 @@
uniform vec3 uVec3;
uniform vec4 uVec4;
+uniform mat2 uMat2;
+uniform mat3 uMat3;
+uniform mat4 uMat4;
+
const int ARRAY_SIZE = 10;
uniform float[ARRAY_SIZE] uFloatArray;
@@ -22,6 +26,10 @@
uniform vec3[ARRAY_SIZE] uVec3Array;
uniform vec4[ARRAY_SIZE] uVec4Array;
+uniform mat2[ARRAY_SIZE] uMat2Array;
+uniform mat3[ARRAY_SIZE] uMat3Array;
+uniform mat4[ARRAY_SIZE] uMat4Array;
+
void main() {
float u = FlutterFragCoord().x / N_COLOR_VALUES;
@@ -50,6 +58,30 @@
}
offset += increment;
+ for (int i = 0; i < 2; ++i) {
+ if (u < offset) {
+ fragColor = vec4(uMat2[i], 0, 1);
+ return;
+ }
+ offset += increment;
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ if (u < offset) {
+ fragColor = vec4(uMat3[i], 1);
+ return;
+ }
+ offset += increment;
+ }
+
+ for (int i = 0; i < 4; ++i) {
+ if (u < offset) {
+ fragColor = uMat4[i];
+ return;
+ }
+ offset += increment;
+ }
+
for (int i = 0; i < ARRAY_SIZE; ++i) {
if (u < offset) {
fragColor = vec4(uFloatArray[i], 0, 0, 1);
@@ -81,4 +113,34 @@
}
offset += increment;
}
+
+ for (int i = 0; i < ARRAY_SIZE; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ if (u < offset) {
+ fragColor = vec4(uMat2Array[i][j], 0, 1);
+ return;
+ }
+ offset += increment;
+ }
+ }
+
+ for (int i = 0; i < ARRAY_SIZE; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ if (u < offset) {
+ fragColor = vec4(uMat3Array[i][j], 1);
+ return;
+ }
+ offset += increment;
+ }
+ }
+
+ for (int i = 0; i < ARRAY_SIZE; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ if (u < offset) {
+ fragColor = uMat4Array[i][j];
+ return;
+ }
+ offset += increment;
+ }
+ }
}
\ No newline at end of file
diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat2_array_uniform.frag b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat2_array_uniform.frag
new file mode 100644
index 0000000..25ba80c
--- /dev/null
+++ b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat2_array_uniform.frag
@@ -0,0 +1,23 @@
+#version 320 es
+
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <flutter/runtime_effect.glsl>
+
+precision highp float;
+
+uniform mat2[2] colors;
+
+out vec4 fragColor;
+
+void main() {
+ vec2 uv = FlutterFragCoord().xy;
+
+ if (uv.x < 1) {
+ fragColor = vec4(colors[0][0], colors[0][1]);
+ } else {
+ fragColor = vec4(colors[1][0], colors[1][1]);
+ }
+}
diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat2_uniform.frag b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat2_uniform.frag
new file mode 100644
index 0000000..9c1e879
--- /dev/null
+++ b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat2_uniform.frag
@@ -0,0 +1,15 @@
+#version 320 es
+
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+precision highp float;
+
+uniform mat2 color_rgba;
+
+out vec4 fragColor;
+
+void main() {
+ fragColor = vec4(color_rgba[0], color_rgba[1]);
+}
diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat3_array_uniform.frag b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat3_array_uniform.frag
new file mode 100644
index 0000000..01c5d25
--- /dev/null
+++ b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat3_array_uniform.frag
@@ -0,0 +1,34 @@
+#version 320 es
+
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// If updating this file, also update
+// engine/src/flutter/lib/web_ui/test/ui/fragment_shader_test.dart
+
+#include <flutter/runtime_effect.glsl>
+
+precision highp float;
+
+uniform mat3[] colors;
+
+out vec4 fragColor;
+
+void main() {
+ vec2 uv = FlutterFragCoord().xy;
+
+ if (uv.x < 1) {
+ fragColor = vec4(colors[0][0], 1);
+ } else if (uv.x < 2) {
+ fragColor = vec4(colors[0][1], 1);
+ } else if (uv.x < 3) {
+ fragColor = vec4(colors[0][2], 1);
+ } else if (uv.x < 4) {
+ fragColor = vec4(colors[1][0], 1);
+ } else if (uv.x < 5) {
+ fragColor = vec4(colors[1][1], 1);
+ } else if (uv.x < 6) {
+ fragColor = vec4(colors[1][2], 1);
+ }
+}
diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat3_uniform.frag b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat3_uniform.frag
new file mode 100644
index 0000000..aeb77ab
--- /dev/null
+++ b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat3_uniform.frag
@@ -0,0 +1,28 @@
+#version 320 es
+
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// If updating this file, also update
+// engine/src/flutter/lib/web_ui/test/ui/fragment_shader_test.dart
+
+#include <flutter/runtime_effect.glsl>
+
+precision highp float;
+
+uniform mat3 colors;
+
+out vec4 fragColor;
+
+void main() {
+ vec2 uv = FlutterFragCoord().xy / 3.0;
+
+ if (uv.x < 0.3) {
+ fragColor = vec4(colors[0], 1);
+ } else if (uv.x < 0.6) {
+ fragColor = vec4(colors[1], 1);
+ } else {
+ fragColor = vec4(colors[2], 1);
+ }
+}
diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat4_array_uniform.frag b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat4_array_uniform.frag
new file mode 100644
index 0000000..2de0560
--- /dev/null
+++ b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat4_array_uniform.frag
@@ -0,0 +1,38 @@
+#version 320 es
+
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// If updating this file, also update
+// engine/src/flutter/lib/web_ui/test/ui/fragment_shader_test.dart
+
+#include <flutter/runtime_effect.glsl>
+
+precision highp float;
+
+uniform mat4[] colors;
+
+out vec4 fragColor;
+
+void main() {
+ vec2 uv = FlutterFragCoord().xy;
+
+ if (uv.x < 1) {
+ fragColor = colors[0][0];
+ } else if (uv.x < 2) {
+ fragColor = colors[0][1];
+ } else if (uv.x < 3) {
+ fragColor = colors[0][2];
+ } else if (uv.x < 4) {
+ fragColor = colors[0][3];
+ } else if (uv.x < 5) {
+ fragColor = colors[1][0];
+ } else if (uv.x < 6) {
+ fragColor = colors[1][1];
+ } else if (uv.x < 7) {
+ fragColor = colors[1][2];
+ } else if (uv.x < 8) {
+ fragColor = colors[1][3];
+ }
+}
diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat4_uniform.frag b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat4_uniform.frag
new file mode 100644
index 0000000..2bff25c
--- /dev/null
+++ b/engine/src/flutter/lib/ui/fixtures/shaders/uniforms/mat4_uniform.frag
@@ -0,0 +1,30 @@
+#version 320 es
+
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// If updating this file, also update
+// engine/src/flutter/lib/web_ui/test/ui/fragment_shader_test.dart
+
+#include <flutter/runtime_effect.glsl>
+
+precision highp float;
+
+uniform mat4 colors;
+
+out vec4 fragColor;
+
+void main() {
+ vec2 uv = FlutterFragCoord().xy / 4.0;
+
+ if (uv.x < 0.25) {
+ fragColor = colors[0];
+ } else if (uv.x < 0.5) {
+ fragColor = colors[1];
+ } else if (uv.x < 0.75) {
+ fragColor = colors[2];
+ } else {
+ fragColor = colors[3];
+ }
+}
diff --git a/engine/src/flutter/lib/ui/painting.dart b/engine/src/flutter/lib/ui/painting.dart
index 6976efd..bfee6f9 100644
--- a/engine/src/flutter/lib/ui/painting.dart
+++ b/engine/src/flutter/lib/ui/painting.dart
@@ -5724,6 +5724,189 @@
final UniformFloatSlot _xSlot, _ySlot, _zSlot, _wSlot;
}
+/// A binding to a uniform of type mat2. Calling [set] on this object updates
+/// the uniform's value.
+///
+/// Example:
+///
+/// ```dart
+/// void updateShader(ui.FragmentShader shader) {
+/// shader.getUniformMat2('uIdentity').set(
+/// 1.0, 0.0,
+/// 0.0, 1.0
+/// );
+/// }
+/// ```
+///
+/// See also:
+/// [FragmentShader.getUniformMat2] - How [UniformMat2Slot] instances are acquired.
+///
+base class UniformMat2Slot extends UniformType {
+ UniformMat2Slot._(this._m00, this._m01, this._m10, this._m11);
+
+ /// Set the float value of the matrix in row-major order.
+ void set(double m00, double m01, double m10, double m11) {
+ _m00.set(m00);
+ _m01.set(m01);
+ _m10.set(m10);
+ _m11.set(m11);
+ }
+
+ final UniformFloatSlot _m00, _m01, _m10, _m11;
+}
+
+/// A binding to a uniform of type mat3. Calling [set] on this object updates
+/// the uniform's value.
+///
+/// Example:
+///
+/// ```dart
+/// void updateShader(ui.FragmentShader shader) {
+/// shader.getUniformMat3('uIdentity').set(
+/// 1.0, 0.0, 0.0,
+/// 0.0, 1.0, 0.0,
+/// 0.0, 0.0, 1.0
+/// );
+/// }
+/// ```
+///
+/// See also:
+/// [FragmentShader.getUniformMat3] - How [UniformMat3Slot] instances are acquired.
+///
+base class UniformMat3Slot extends UniformType {
+ UniformMat3Slot._(
+ this._m00,
+ this._m01,
+ this._m02,
+ this._m10,
+ this._m11,
+ this._m12,
+ this._m20,
+ this._m21,
+ this._m22,
+ );
+
+ /// Set the float value of the matrix in row-major order.
+ void set(
+ double m00,
+ double m01,
+ double m02,
+ double m10,
+ double m11,
+ double m12,
+ double m20,
+ double m21,
+ double m22,
+ ) {
+ _m00.set(m00);
+ _m01.set(m01);
+ _m02.set(m02);
+ _m10.set(m10);
+ _m11.set(m11);
+ _m12.set(m12);
+ _m20.set(m20);
+ _m21.set(m21);
+ _m22.set(m22);
+ }
+
+ final UniformFloatSlot _m00, _m01, _m02, _m10, _m11, _m12, _m20, _m21, _m22;
+}
+
+/// A binding to a uniform of type mat4. Calling [set] on this object updates
+/// the uniform's value.
+///
+/// Example:
+///
+/// ```dart
+/// void updateShader(ui.FragmentShader shader) {
+/// shader.getUniformMat4('uIdentity').set(
+/// 1.0, 0.0, 0.0, 0.0,
+/// 0.0, 1.0, 0.0, 0.0,
+/// 0.0, 0.0, 1.0, 0.0,
+/// 0.0, 0.0, 0.0, 1.0
+/// );
+/// }
+/// ```
+///
+/// See also:
+/// [FragmentShader.getUniformMat4] - How [UniformMat4Slot] instances are acquired.
+///
+
+base class UniformMat4Slot extends UniformType {
+ UniformMat4Slot._(
+ this._m00,
+ this._m01,
+ this._m02,
+ this._m03,
+ this._m10,
+ this._m11,
+ this._m12,
+ this._m13,
+ this._m20,
+ this._m21,
+ this._m22,
+ this._m23,
+ this._m30,
+ this._m31,
+ this._m32,
+ this._m33,
+ );
+
+ /// Set the float value of the matrix in row-major order.
+ void set(
+ double m00,
+ double m01,
+ double m02,
+ double m03,
+ double m10,
+ double m11,
+ double m12,
+ double m13,
+ double m20,
+ double m21,
+ double m22,
+ double m23,
+ double m30,
+ double m31,
+ double m32,
+ double m33,
+ ) {
+ _m00.set(m00);
+ _m01.set(m01);
+ _m02.set(m02);
+ _m03.set(m03);
+ _m10.set(m10);
+ _m11.set(m11);
+ _m12.set(m12);
+ _m13.set(m13);
+ _m20.set(m20);
+ _m21.set(m21);
+ _m22.set(m22);
+ _m23.set(m23);
+ _m30.set(m30);
+ _m31.set(m31);
+ _m32.set(m32);
+ _m33.set(m33);
+ }
+
+ final UniformFloatSlot _m00,
+ _m01,
+ _m02,
+ _m03,
+ _m10,
+ _m11,
+ _m12,
+ _m13,
+ _m20,
+ _m21,
+ _m22,
+ _m23,
+ _m30,
+ _m31,
+ _m32,
+ _m33;
+}
+
/// An array of bindings to uniforms of the same type T. Access elements via [] and
/// set them individually.
/// Example:
@@ -5964,6 +6147,87 @@
return UniformVec4Slot._(slots[0], slots[1], slots[2], slots[3]);
}
+ /// Access the float binding for a mat2 uniform named [name].
+ ///
+ /// Example:
+ ///
+ /// ```glsl
+ /// uniform mat2 uIdentity;
+ /// ```
+ ///
+ /// ```dart
+ /// void updateShader(ui.FragmentShader shader) {
+ /// shader.getUniformMat2('uIdentity');
+ /// }
+ /// ```
+ UniformMat2Slot getUniformMat2(String name) {
+ final List<UniformFloatSlot> slots = _getSlotsForUniform(name, 4);
+ return UniformMat2Slot._(slots[0], slots[1], slots[2], slots[3]);
+ }
+
+ /// Access the float binding for a mat3 uniform named [name].
+ ///
+ /// Example:
+ ///
+ /// ```glsl
+ /// uniform mat3 uIdentity;
+ /// ```
+ ///
+ /// ```dart
+ /// void updateShader(ui.FragmentShader shader) {
+ /// shader.getUniformMat3('uIdentity');
+ /// }
+ /// ```
+ UniformMat3Slot getUniformMat3(String name) {
+ final List<UniformFloatSlot> slots = _getSlotsForUniform(name, 9);
+ return UniformMat3Slot._(
+ slots[0],
+ slots[1],
+ slots[2],
+ slots[3],
+ slots[4],
+ slots[5],
+ slots[6],
+ slots[7],
+ slots[8],
+ );
+ }
+
+ /// Access the float binding for a mat4 uniform named [name].
+ ///
+ /// Example:
+ ///
+ /// ```glsl
+ /// uniform mat4 uIdentity;
+ /// ```
+ ///
+ /// ```dart
+ /// void updateShader(ui.FragmentShader shader) {
+ /// shader.getUniformMat4('uIdentity');
+ /// }
+ /// ```
+ UniformMat4Slot getUniformMat4(String name) {
+ final List<UniformFloatSlot> slots = _getSlotsForUniform(name, 16);
+ return UniformMat4Slot._(
+ slots[0],
+ slots[1],
+ slots[2],
+ slots[3],
+ slots[4],
+ slots[5],
+ slots[6],
+ slots[7],
+ slots[8],
+ slots[9],
+ slots[10],
+ slots[11],
+ slots[12],
+ slots[13],
+ slots[14],
+ slots[15],
+ );
+ }
+
UniformArray<T> _getUniformArray<T extends UniformType>(
String name,
int elementSize,
@@ -6084,6 +6348,111 @@
);
}
+ /// Access the binding for a mat2[] uniform named [name].
+ ///
+ /// Example:
+ ///
+ /// ```glsl
+ /// uniform mat2[10] uMatricies;
+ /// ```
+ ///
+ /// ```dart
+ /// void updateShader(ui.FragmentShader shader) {
+ /// final ui.UniformArray<ui.UniformMat2Slot> mats = shader.getUniformMat2Array('uMatricies');
+ /// mats[0].set(
+ /// 1.0, 0.0,
+ /// 1.0, 0.5
+ /// );
+ /// }
+ /// ```
+ UniformArray<UniformMat2Slot> getUniformMat2Array(String name) {
+ return _getUniformArray<UniformMat2Slot>(
+ name,
+ 4,
+ (components) => UniformMat2Slot._(components[0], components[1], components[2], components[3]),
+ );
+ }
+
+ /// Access the binding for a mat3[] uniform named [name].
+ ///
+ /// Example:
+ ///
+ /// ```glsl
+ /// uniform mat3[10] uMatricies;
+ /// ```
+ ///
+ /// ```dart
+ /// void updateShader(ui.FragmentShader shader) {
+ /// final ui.UniformArray<ui.UniformMat3Slot> mats = shader.getUniformMat3Array('uMatricies');
+ /// mats[0].set(
+ /// 1.0, 0.0, 0.0,
+ /// 1.0, 0.5, 0.0,
+ /// 1.0, 0.3, 1.2
+ /// );
+ /// }
+ /// ```
+ UniformArray<UniformMat3Slot> getUniformMat3Array(String name) {
+ return _getUniformArray<UniformMat3Slot>(
+ name,
+ 9,
+ (components) => UniformMat3Slot._(
+ components[0],
+ components[1],
+ components[2],
+ components[3],
+ components[4],
+ components[5],
+ components[6],
+ components[7],
+ components[8],
+ ),
+ );
+ }
+
+ /// Access the binding for a mat4[] uniform named [name].
+ ///
+ /// Example:
+ ///
+ /// ```glsl
+ /// uniform mat4[10] uMatricies;
+ /// ```
+ ///
+ /// ```dart
+ /// void updateShader(ui.FragmentShader shader) {
+ /// final ui.UniformArray<ui.UniformMat4Slot> mats = shader.getUniformMat4Array('uMatricies');
+ /// mats[0].set(
+ /// 1.0, 0.0, 0.0, 1.0,
+ /// 1.0, 0.5, 0.0, 0.4,
+ /// 1.0, 0.3, 1.2, 0.2,
+ /// 0.0, 0.0, 1.0, 0.3,
+ /// );
+ /// }
+ /// ```
+ UniformArray<UniformMat4Slot> getUniformMat4Array(String name) {
+ return _getUniformArray<UniformMat4Slot>(
+ name,
+ 16, // 4 floats per element
+ (components) => UniformMat4Slot._(
+ components[0],
+ components[1],
+ components[2],
+ components[3],
+ components[4],
+ components[5],
+ components[6],
+ components[7],
+ components[8],
+ components[9],
+ components[10],
+ components[11],
+ components[12],
+ components[13],
+ components[14],
+ components[15],
+ ),
+ );
+ }
+
/// Access the [ImageSamplerSlot] binding associated with the sampler named
/// [name].
///
diff --git a/engine/src/flutter/lib/web_ui/lib/painting.dart b/engine/src/flutter/lib/web_ui/lib/painting.dart
index 6f1572e..4770584 100644
--- a/engine/src/flutter/lib/web_ui/lib/painting.dart
+++ b/engine/src/flutter/lib/web_ui/lib/painting.dart
@@ -1127,6 +1127,45 @@
void set(double x, double y, double z, double w);
}
+abstract class UniformMat2Slot extends UniformType {
+ void set(double m00, double m01, double m10, double m11);
+}
+
+abstract class UniformMat3Slot extends UniformType {
+ void set(
+ double m00,
+ double m01,
+ double m02,
+ double m10,
+ double m11,
+ double m12,
+ double m20,
+ double m21,
+ double m22,
+ );
+}
+
+abstract class UniformMat4Slot extends UniformType {
+ void set(
+ double m00,
+ double m01,
+ double m02,
+ double m03,
+ double m10,
+ double m11,
+ double m12,
+ double m13,
+ double m20,
+ double m21,
+ double m22,
+ double m23,
+ double m30,
+ double m31,
+ double m32,
+ double m33,
+ );
+}
+
abstract class UniformArray<T extends UniformType> {
T operator [](int index);
int get length;
@@ -1157,6 +1196,12 @@
UniformVec4Slot getUniformVec4(String name);
+ UniformMat2Slot getUniformMat2(String name);
+
+ UniformMat3Slot getUniformMat3(String name);
+
+ UniformMat4Slot getUniformMat4(String name);
+
UniformArray<UniformFloatSlot> getUniformFloatArray(String name);
UniformArray<UniformVec2Slot> getUniformVec2Array(String name);
@@ -1165,5 +1210,11 @@
UniformArray<UniformVec4Slot> getUniformVec4Array(String name);
+ UniformArray<UniformMat2Slot> getUniformMat2Array(String name);
+
+ UniformArray<UniformMat3Slot> getUniformMat3Array(String name);
+
+ UniformArray<UniformMat4Slot> getUniformMat4Array(String name);
+
ImageSamplerSlot getImageSampler(String name);
}
diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/painting.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/painting.dart
index f93f996..f0a5726 100644
--- a/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/painting.dart
+++ b/engine/src/flutter/lib/web_ui/lib/src/engine/canvaskit/painting.dart
@@ -511,6 +511,36 @@
}
@override
+ ui.UniformMat2Slot getUniformMat2(String name) {
+ throw UnsupportedError('getUniformMat2 is not supported on the web.');
+ }
+
+ @override
+ ui.UniformMat3Slot getUniformMat3(String name) {
+ throw UnsupportedError('getUniformMat3 is not supported on the web.');
+ }
+
+ @override
+ ui.UniformMat4Slot getUniformMat4(String name) {
+ throw UnsupportedError('getUniformMat4 is not supported on the web.');
+ }
+
+ @override
+ ui.UniformArray<ui.UniformMat2Slot> getUniformMat2Array(String name) {
+ throw UnsupportedError('getUniformMat2Array is not supported on the web.');
+ }
+
+ @override
+ ui.UniformArray<ui.UniformMat3Slot> getUniformMat3Array(String name) {
+ throw UnsupportedError('getUniformMat3Array is not supported on the web.');
+ }
+
+ @override
+ ui.UniformArray<ui.UniformMat4Slot> getUniformMat4Array(String name) {
+ throw UnsupportedError('getUniformMat4Array is not supported on the web.');
+ }
+
+ @override
ui.ImageSamplerSlot getImageSampler(String name) {
throw UnsupportedError('getImageSampler is not supported on the web.');
}
diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/shaders.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/shaders.dart
index 1efb091..81e5cd54 100644
--- a/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/shaders.dart
+++ b/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/shaders.dart
@@ -398,6 +398,36 @@
}
@override
+ ui.UniformMat2Slot getUniformMat2(String name) {
+ throw UnsupportedError('getUniformMat2 is not supported on the web.');
+ }
+
+ @override
+ ui.UniformMat3Slot getUniformMat3(String name) {
+ throw UnsupportedError('getUniformMat3 is not supported on the web.');
+ }
+
+ @override
+ ui.UniformMat4Slot getUniformMat4(String name) {
+ throw UnsupportedError('getUniformMat4 is not supported on the web.');
+ }
+
+ @override
+ ui.UniformArray<ui.UniformMat2Slot> getUniformMat2Array(String name) {
+ throw UnsupportedError('getUniformMat2Array is not supported on the web.');
+ }
+
+ @override
+ ui.UniformArray<ui.UniformMat3Slot> getUniformMat3Array(String name) {
+ throw UnsupportedError('getUniformMat3Array is not supported on the web.');
+ }
+
+ @override
+ ui.UniformArray<ui.UniformMat4Slot> getUniformMat4Array(String name) {
+ throw UnsupportedError('getUniformMat4Array is not supported on the web.');
+ }
+
+ @override
ui.ImageSamplerSlot getImageSampler(String name) {
throw UnsupportedError('getImageSampler is not supported on the web.');
}
diff --git a/engine/src/flutter/testing/dart/fragment_shader_test.dart b/engine/src/flutter/testing/dart/fragment_shader_test.dart
index 8c85b2e..12550ab 100644
--- a/engine/src/flutter/testing/dart/fragment_shader_test.dart
+++ b/engine/src/flutter/testing/dart/fragment_shader_test.dart
@@ -94,6 +94,15 @@
UniformVec4Slot: (await FragmentProgram.fromAsset(
'vec4_uniform.frag.iplr',
)).fragmentShader(),
+ UniformMat2Slot: (await FragmentProgram.fromAsset(
+ 'mat2_uniform.frag.iplr',
+ )).fragmentShader(),
+ UniformMat3Slot: (await FragmentProgram.fromAsset(
+ 'mat3_uniform.frag.iplr',
+ )).fragmentShader(),
+ UniformMat4Slot: (await FragmentProgram.fromAsset(
+ 'mat4_uniform.frag.iplr',
+ )).fragmentShader(),
UniformArray<UniformFloatSlot>: (await FragmentProgram.fromAsset(
'float_array_uniform.frag.iplr',
)).fragmentShader(),
@@ -106,6 +115,15 @@
UniformArray<UniformVec4Slot>: (await FragmentProgram.fromAsset(
'vec4_array_uniform.frag.iplr',
)).fragmentShader(),
+ UniformArray<UniformMat2Slot>: (await FragmentProgram.fromAsset(
+ 'mat2_array_uniform.frag.iplr',
+ )).fragmentShader(),
+ UniformArray<UniformMat3Slot>: (await FragmentProgram.fromAsset(
+ 'mat3_array_uniform.frag.iplr',
+ )).fragmentShader(),
+ UniformArray<UniformMat4Slot>: (await FragmentProgram.fromAsset(
+ 'mat4_array_uniform.frag.iplr',
+ )).fragmentShader(),
};
});
@@ -250,6 +268,177 @@
});
});
+ group('mat2', () {
+ test('set using setFloat', () async {
+ const color = Color.fromARGB(255, 67, 42, 12);
+ final FragmentShader shader = shaderMap[UniformMat2Slot]!;
+ shader.setFloat(0, color.r);
+ shader.setFloat(1, color.g);
+ shader.setFloat(2, color.b);
+ shader.setFloat(3, color.a);
+ _expectShaderRendersColor(shader, color);
+ });
+
+ test('set using getUniformMat2', () async {
+ const color = Color.fromARGB(255, 12, 37, 27);
+ final FragmentShader shader = shaderMap[UniformMat2Slot]!;
+ shader.getUniformMat2('color_rgba').set(color.r, color.g, color.b, color.a);
+ _expectShaderRendersColor(shader, color);
+ });
+
+ test('wrong datatype', () async {
+ final FragmentShader shader = shaderMap[UniformVec3Slot]!;
+ expect(
+ () => shader.getUniformMat2('color_rgb'),
+ throwsA(
+ isA<ArgumentError>().having(
+ (e) => e.message,
+ 'message',
+ contains('`color_rgb` has size 3, not size 4.'),
+ ),
+ ),
+ );
+ });
+ });
+
+ group('mat3', () {
+ test('set using setFloat', () async {
+ const cpuColors = [
+ Color.fromARGB(255, 67, 42, 12),
+ Color.fromARGB(255, 11, 22, 96),
+ Color.fromARGB(255, 8, 16, 67),
+ ];
+ final FragmentShader shader = shaderMap[UniformMat3Slot]!;
+ shader.setFloat(0, cpuColors[0].r);
+ shader.setFloat(1, cpuColors[0].g);
+ shader.setFloat(2, cpuColors[0].b);
+ shader.setFloat(3, cpuColors[1].r);
+ shader.setFloat(4, cpuColors[1].g);
+ shader.setFloat(5, cpuColors[1].b);
+ shader.setFloat(6, cpuColors[2].r);
+ shader.setFloat(7, cpuColors[2].g);
+ shader.setFloat(8, cpuColors[2].b);
+ _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('set using getUniformMat3', () async {
+ const cpuColors = [
+ Color.fromARGB(255, 11, 22, 96),
+ Color.fromARGB(255, 8, 16, 67),
+ Color.fromARGB(255, 67, 42, 12),
+ ];
+ final FragmentShader shader = shaderMap[UniformMat3Slot]!;
+ final UniformMat3Slot gpuColors = shader.getUniformMat3('colors');
+ gpuColors.set(
+ cpuColors[0].r,
+ cpuColors[0].g,
+ cpuColors[0].b,
+
+ cpuColors[1].r,
+ cpuColors[1].g,
+ cpuColors[1].b,
+
+ cpuColors[2].r,
+ cpuColors[2].g,
+ cpuColors[2].b,
+ );
+ _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('wrong datatype', () async {
+ final FragmentShader shader = shaderMap[UniformVec3Slot]!;
+ expect(
+ () => shader.getUniformMat3('color_rgb'),
+ throwsA(
+ isA<ArgumentError>().having(
+ (e) => e.message,
+ 'message',
+ contains('Uniform `color_rgb` has size 3, not size 9.'),
+ ),
+ ),
+ );
+ });
+ });
+
+ group('mat4', () {
+ test('set using setFloat', () async {
+ const cpuColors = [
+ Color.fromARGB(6, 67, 42, 12),
+ Color.fromARGB(33, 11, 22, 96),
+ Color.fromARGB(99, 8, 16, 67),
+ Color.fromARGB(120, 11, 22, 96),
+ ];
+ final FragmentShader shader = shaderMap[UniformMat4Slot]!;
+ shader.setFloat(0, cpuColors[0].r);
+ shader.setFloat(1, cpuColors[0].g);
+ shader.setFloat(2, cpuColors[0].b);
+ shader.setFloat(3, cpuColors[0].a);
+
+ shader.setFloat(4, cpuColors[1].r);
+ shader.setFloat(5, cpuColors[1].g);
+ shader.setFloat(6, cpuColors[1].b);
+ shader.setFloat(7, cpuColors[1].a);
+
+ shader.setFloat(8, cpuColors[2].r);
+ shader.setFloat(9, cpuColors[2].g);
+ shader.setFloat(10, cpuColors[2].b);
+ shader.setFloat(11, cpuColors[2].a);
+
+ shader.setFloat(12, cpuColors[3].r);
+ shader.setFloat(13, cpuColors[3].g);
+ shader.setFloat(14, cpuColors[3].b);
+ shader.setFloat(15, cpuColors[3].a);
+ _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('set using getUniformMat4', () async {
+ const cpuColors = [
+ Color.fromARGB(78, 11, 22, 96),
+ Color.fromARGB(255, 8, 16, 67),
+ Color.fromARGB(99, 11, 22, 96),
+ Color.fromARGB(46, 67, 42, 12),
+ ];
+ final FragmentShader shader = shaderMap[UniformMat4Slot]!;
+ final UniformMat4Slot gpuColors = shader.getUniformMat4('colors');
+ gpuColors.set(
+ cpuColors[0].r,
+ cpuColors[0].g,
+ cpuColors[0].b,
+ cpuColors[0].a,
+
+ cpuColors[1].r,
+ cpuColors[1].g,
+ cpuColors[1].b,
+ cpuColors[1].a,
+
+ cpuColors[2].r,
+ cpuColors[2].g,
+ cpuColors[2].b,
+ cpuColors[2].a,
+
+ cpuColors[3].r,
+ cpuColors[3].g,
+ cpuColors[3].b,
+ cpuColors[3].a,
+ );
+ _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('wrong datatype', () async {
+ final FragmentShader shader = shaderMap[UniformVec3Slot]!;
+ expect(
+ () => shader.getUniformMat4('color_rgb'),
+ throwsA(
+ isA<ArgumentError>().having(
+ (e) => e.message,
+ 'message',
+ contains('Uniform `color_rgb` has size 3, not size 16.'),
+ ),
+ ),
+ );
+ });
+ });
+
group('float array', () {
test('set using setFloat', () {
const color = Color.fromARGB(255, 11, 22, 96);
@@ -391,6 +580,265 @@
});
});
+ group('mat2 array', () {
+ test('set using setFloat', () async {
+ const cpuColors = [Color.fromARGB(77, 67, 42, 12), Color.fromARGB(51, 11, 22, 96)];
+ final FragmentShader shader = shaderMap[UniformArray<UniformMat2Slot>]!;
+ shader.setFloat(0, cpuColors[0].r);
+ shader.setFloat(1, cpuColors[0].g);
+ shader.setFloat(2, cpuColors[0].b);
+ shader.setFloat(3, cpuColors[0].a);
+ shader.setFloat(4, cpuColors[1].r);
+ shader.setFloat(5, cpuColors[1].g);
+ shader.setFloat(6, cpuColors[1].b);
+ shader.setFloat(7, cpuColors[1].a);
+ _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('set using getUniformMat2', () async {
+ const cpuColors = [Color.fromARGB(51, 11, 22, 96), Color.fromARGB(77, 67, 42, 12)];
+ final FragmentShader shader = shaderMap[UniformArray<UniformMat2Slot>]!;
+ final UniformArray<UniformMat2Slot> colors = shader.getUniformMat2Array('colors');
+ colors[0].set(cpuColors[0].r, cpuColors[0].g, cpuColors[0].b, cpuColors[0].a);
+ colors[1].set(cpuColors[1].r, cpuColors[1].g, cpuColors[1].b, cpuColors[1].a);
+ _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('wrong datatype', () async {
+ final FragmentShader shader = shaderMap[UniformVec3Slot]!;
+ expect(
+ () => shader.getUniformMat2Array('color_rgb'),
+ throwsA(
+ isA<ArgumentError>().having(
+ (e) => e.message,
+ 'message',
+ contains('Uniform size (3) for "color_rgb" is not a multiple of 4.'),
+ ),
+ ),
+ );
+ });
+ });
+
+ group('mat4 array', () {
+ test('set using setFloat', () async {
+ const cpuColors = [
+ Color.fromARGB(31, 8, 16, 67),
+ Color.fromARGB(29, 11, 22, 96),
+ Color.fromARGB(43, 32, 34, 36),
+ Color.fromARGB(41, 26, 28, 30),
+ Color.fromARGB(39, 20, 22, 24),
+ Color.fromARGB(37, 14, 16, 18),
+ Color.fromARGB(35, 8, 10, 12),
+ Color.fromARGB(33, 2, 4, 6),
+ ];
+ final FragmentShader shader = shaderMap[UniformArray<UniformMat4Slot>]!;
+ shader.setFloat(0, cpuColors[0].r);
+ shader.setFloat(1, cpuColors[0].g);
+ shader.setFloat(2, cpuColors[0].b);
+ shader.setFloat(3, cpuColors[0].a);
+
+ shader.setFloat(4, cpuColors[1].r);
+ shader.setFloat(5, cpuColors[1].g);
+ shader.setFloat(6, cpuColors[1].b);
+ shader.setFloat(7, cpuColors[1].a);
+
+ shader.setFloat(8, cpuColors[2].r);
+ shader.setFloat(9, cpuColors[2].g);
+ shader.setFloat(10, cpuColors[2].b);
+ shader.setFloat(11, cpuColors[2].a);
+
+ shader.setFloat(12, cpuColors[3].r);
+ shader.setFloat(13, cpuColors[3].g);
+ shader.setFloat(14, cpuColors[3].b);
+ shader.setFloat(15, cpuColors[3].a);
+
+ shader.setFloat(16, cpuColors[4].r);
+ shader.setFloat(17, cpuColors[4].g);
+ shader.setFloat(18, cpuColors[4].b);
+ shader.setFloat(19, cpuColors[4].a);
+
+ shader.setFloat(20, cpuColors[5].r);
+ shader.setFloat(21, cpuColors[5].g);
+ shader.setFloat(22, cpuColors[5].b);
+ shader.setFloat(23, cpuColors[5].a);
+
+ shader.setFloat(24, cpuColors[6].r);
+ shader.setFloat(25, cpuColors[6].g);
+ shader.setFloat(26, cpuColors[6].b);
+ shader.setFloat(27, cpuColors[6].a);
+
+ shader.setFloat(28, cpuColors[7].r);
+ shader.setFloat(29, cpuColors[7].g);
+ shader.setFloat(30, cpuColors[7].b);
+ shader.setFloat(31, cpuColors[7].a);
+
+ await _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('set using getUniformMat4Array', () async {
+ const cpuColors = [
+ Color.fromARGB(29, 11, 22, 96),
+ Color.fromARGB(31, 8, 16, 67),
+ Color.fromARGB(33, 2, 4, 6),
+ Color.fromARGB(35, 8, 10, 12),
+ Color.fromARGB(37, 14, 16, 18),
+ Color.fromARGB(39, 20, 22, 24),
+ Color.fromARGB(41, 26, 28, 30),
+ Color.fromARGB(43, 32, 34, 36),
+ ];
+ final FragmentShader shader = shaderMap[UniformArray<UniformMat4Slot>]!;
+ final UniformArray<UniformMat4Slot> colors = shader.getUniformMat4Array('colors');
+ colors[0].set(
+ cpuColors[0].r,
+ cpuColors[0].g,
+ cpuColors[0].b,
+ cpuColors[0].a,
+
+ cpuColors[1].r,
+ cpuColors[1].g,
+ cpuColors[1].b,
+ cpuColors[1].a,
+
+ cpuColors[2].r,
+ cpuColors[2].g,
+ cpuColors[2].b,
+ cpuColors[2].a,
+
+ cpuColors[3].r,
+ cpuColors[3].g,
+ cpuColors[3].b,
+ cpuColors[3].a,
+ );
+
+ colors[1].set(
+ cpuColors[4].r,
+ cpuColors[4].g,
+ cpuColors[4].b,
+ cpuColors[4].a,
+
+ cpuColors[5].r,
+ cpuColors[5].g,
+ cpuColors[5].b,
+ cpuColors[5].a,
+
+ cpuColors[6].r,
+ cpuColors[6].g,
+ cpuColors[6].b,
+ cpuColors[6].a,
+
+ cpuColors[7].r,
+ cpuColors[7].g,
+ cpuColors[7].b,
+ cpuColors[7].a,
+ );
+ await _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('wrong datatype', () async {
+ final FragmentShader shader = shaderMap[UniformVec3Slot]!;
+ expect(
+ () => shader.getUniformMat4Array('color_rgb'),
+ throwsA(
+ isA<ArgumentError>().having(
+ (e) => e.message,
+ 'message',
+ contains('Uniform size (3) for "color_rgb" is not a multiple of 16.'),
+ ),
+ ),
+ );
+ });
+ });
+
+ group('mat3 array', () {
+ test('set using setFloat', () async {
+ const cpuColors = [
+ Color.fromARGB(255, 67, 42, 12),
+ Color.fromARGB(255, 11, 22, 96),
+ Color.fromARGB(255, 2, 4, 6),
+ Color.fromARGB(255, 8, 10, 12),
+ Color.fromARGB(255, 14, 16, 18),
+ Color.fromARGB(255, 20, 22, 24),
+ ];
+ final FragmentShader shader = shaderMap[UniformArray<UniformMat3Slot>]!;
+ shader.setFloat(0, cpuColors[0].r);
+ shader.setFloat(1, cpuColors[0].g);
+ shader.setFloat(2, cpuColors[0].b);
+
+ shader.setFloat(3, cpuColors[1].r);
+ shader.setFloat(4, cpuColors[1].g);
+ shader.setFloat(5, cpuColors[1].b);
+
+ shader.setFloat(6, cpuColors[2].r);
+ shader.setFloat(7, cpuColors[2].g);
+ shader.setFloat(8, cpuColors[2].b);
+
+ shader.setFloat(9, cpuColors[3].r);
+ shader.setFloat(10, cpuColors[3].g);
+ shader.setFloat(11, cpuColors[3].b);
+
+ shader.setFloat(12, cpuColors[4].r);
+ shader.setFloat(13, cpuColors[4].g);
+ shader.setFloat(14, cpuColors[4].b);
+
+ shader.setFloat(15, cpuColors[5].r);
+ shader.setFloat(16, cpuColors[5].g);
+ shader.setFloat(17, cpuColors[5].b);
+
+ await _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('set using getUniformMat3Array', () async {
+ const cpuColors = [
+ Color.fromARGB(255, 67, 42, 12),
+ Color.fromARGB(255, 11, 22, 96),
+ Color.fromARGB(255, 2, 4, 6),
+ Color.fromARGB(255, 8, 10, 12),
+ Color.fromARGB(255, 14, 16, 18),
+ Color.fromARGB(255, 20, 22, 24),
+ ];
+ final FragmentShader shader = shaderMap[UniformArray<UniformMat3Slot>]!;
+ final UniformArray<UniformMat3Slot> colors = shader.getUniformMat3Array('colors');
+ colors[0].set(
+ cpuColors[0].r,
+ cpuColors[0].g,
+ cpuColors[0].b,
+ cpuColors[1].r,
+ cpuColors[1].g,
+ cpuColors[1].b,
+ cpuColors[2].r,
+ cpuColors[2].g,
+ cpuColors[2].b,
+ );
+
+ colors[1].set(
+ cpuColors[3].r,
+ cpuColors[3].g,
+ cpuColors[3].b,
+ cpuColors[4].r,
+ cpuColors[4].g,
+ cpuColors[4].b,
+ cpuColors[5].r,
+ cpuColors[5].g,
+ cpuColors[5].b,
+ );
+ await _expectShaderRendersBarcode(shader, cpuColors);
+ });
+
+ test('wrong datatype', () async {
+ final FragmentShader shader = shaderMap[UniformVec3Slot]!;
+ expect(
+ () => shader.getUniformMat3Array('color_rgb'),
+ throwsA(
+ isA<ArgumentError>().having(
+ (e) => e.message,
+ 'message',
+ contains('Uniform size (3) for "color_rgb" is not a multiple of 9.'),
+ ),
+ ),
+ );
+ });
+ });
+
group('all uniforms', () {
late FragmentProgram program;
late List<Color> cpuColors;
@@ -418,19 +866,44 @@
random.nextInt(255),
),
);
- for (var i = 0; i < 10; ++i) {
- cpuColors.add(Color.fromARGB(255, random.nextInt(255), 0, 0));
- }
-
- for (var i = 0; i < 10; ++i) {
+ // uMat2
+ for (var i = 0; i < 2; ++i) {
cpuColors.add(Color.fromARGB(255, random.nextInt(255), random.nextInt(255), 0));
}
+ // uMat3
+ for (var i = 0; i < 3; ++i) {
+ cpuColors.add(
+ Color.fromARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255)),
+ );
+ }
+
+ // uMat4
+ for (var i = 0; i < 4; ++i) {
+ cpuColors.add(
+ Color.fromARGB(
+ random.nextInt(255),
+ random.nextInt(255),
+ random.nextInt(255),
+ random.nextInt(255),
+ ),
+ );
+ }
+ // uFloatArray
+ for (var i = 0; i < 10; ++i) {
+ cpuColors.add(Color.fromARGB(255, random.nextInt(255), 0, 0));
+ }
+ // uVec2Array
+ for (var i = 0; i < 10; ++i) {
+ cpuColors.add(Color.fromARGB(255, random.nextInt(255), random.nextInt(255), 0));
+ }
+ // uVec3Array
for (var i = 0; i < 10; ++i) {
cpuColors.add(
Color.fromARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255)),
);
}
+ // uVec4Array
for (var i = 0; i < 10; ++i) {
cpuColors.add(
Color.fromARGB(
@@ -441,6 +914,30 @@
),
);
}
+
+ // uMat2Array
+ for (var i = 0; i < 20; ++i) {
+ cpuColors.add(Color.fromARGB(255, random.nextInt(255), random.nextInt(255), 0));
+ }
+
+ // uMat3Array
+ for (var i = 0; i < 30; ++i) {
+ cpuColors.add(
+ Color.fromARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255)),
+ );
+ }
+
+ // uMat4Array
+ for (var i = 0; i < 40; ++i) {
+ cpuColors.add(
+ Color.fromARGB(
+ random.nextInt(255),
+ random.nextInt(255),
+ random.nextInt(255),
+ random.nextInt(255),
+ ),
+ );
+ }
});
test('set using setFloat', () async {
@@ -460,8 +957,49 @@
shader.setFloat(8, cpuColors[3].b);
shader.setFloat(9, cpuColors[3].a);
- var shaderOffset = 10;
- var colorOffset = 4;
+ //uMat2
+ shader.setFloat(10, cpuColors[4].r);
+ shader.setFloat(11, cpuColors[4].g);
+
+ shader.setFloat(12, cpuColors[5].r);
+ shader.setFloat(13, cpuColors[5].g);
+
+ //uMat3
+ shader.setFloat(14, cpuColors[6].r);
+ shader.setFloat(15, cpuColors[6].g);
+ shader.setFloat(16, cpuColors[6].b);
+
+ shader.setFloat(17, cpuColors[7].r);
+ shader.setFloat(18, cpuColors[7].g);
+ shader.setFloat(19, cpuColors[7].b);
+
+ shader.setFloat(20, cpuColors[8].r);
+ shader.setFloat(21, cpuColors[8].g);
+ shader.setFloat(22, cpuColors[8].b);
+
+ //uMat4
+ shader.setFloat(23, cpuColors[9].r);
+ shader.setFloat(24, cpuColors[9].g);
+ shader.setFloat(25, cpuColors[9].b);
+ shader.setFloat(26, cpuColors[9].a);
+
+ shader.setFloat(27, cpuColors[10].r);
+ shader.setFloat(28, cpuColors[10].g);
+ shader.setFloat(29, cpuColors[10].b);
+ shader.setFloat(30, cpuColors[10].a);
+
+ shader.setFloat(31, cpuColors[11].r);
+ shader.setFloat(32, cpuColors[11].g);
+ shader.setFloat(33, cpuColors[11].b);
+ shader.setFloat(34, cpuColors[11].a);
+
+ shader.setFloat(35, cpuColors[12].r);
+ shader.setFloat(36, cpuColors[12].g);
+ shader.setFloat(37, cpuColors[12].b);
+ shader.setFloat(38, cpuColors[12].a);
+
+ var shaderOffset = 39;
+ var colorOffset = 13;
for (var i = 0; i < 10; ++i) {
shader.setFloat(shaderOffset++, cpuColors[colorOffset++].r);
@@ -481,6 +1019,22 @@
shader.setFloat(shaderOffset++, cpuColors[colorOffset].b);
shader.setFloat(shaderOffset++, cpuColors[colorOffset++].a);
}
+ for (var i = 0; i < 20; ++i) {
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset].r);
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset++].g);
+ }
+ for (var i = 0; i < 30; ++i) {
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset].r);
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset].g);
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset++].b);
+ }
+ for (var i = 0; i < 40; ++i) {
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset].r);
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset].g);
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset].b);
+ shader.setFloat(shaderOffset++, cpuColors[colorOffset++].a);
+ }
+
_expectShaderRendersBarcode(shader, cpuColors);
});
@@ -493,14 +1047,59 @@
.getUniformVec4('uVec4')
.set(cpuColors[3].r, cpuColors[3].g, cpuColors[3].b, cpuColors[3].a);
+ shader
+ .getUniformMat2('uMat2')
+ .set(cpuColors[4].r, cpuColors[4].g, cpuColors[5].r, cpuColors[5].g);
+
+ shader
+ .getUniformMat3('uMat3')
+ .set(
+ cpuColors[6].r,
+ cpuColors[6].g,
+ cpuColors[6].b,
+ cpuColors[7].r,
+ cpuColors[7].g,
+ cpuColors[7].b,
+ cpuColors[8].r,
+ cpuColors[8].g,
+ cpuColors[8].b,
+ );
+
+ shader
+ .getUniformMat4('uMat4')
+ .set(
+ cpuColors[9].r,
+ cpuColors[9].g,
+ cpuColors[9].b,
+ cpuColors[9].a,
+
+ cpuColors[10].r,
+ cpuColors[10].g,
+ cpuColors[10].b,
+ cpuColors[10].a,
+
+ cpuColors[11].r,
+ cpuColors[11].g,
+ cpuColors[11].b,
+ cpuColors[11].a,
+
+ cpuColors[12].r,
+ cpuColors[12].g,
+ cpuColors[12].b,
+ cpuColors[12].a,
+ );
+
final UniformArray<UniformFloatSlot> floatArray = shader.getUniformFloatArray(
'uFloatArray',
);
final UniformArray<UniformVec2Slot> vec2Array = shader.getUniformVec2Array('uVec2Array');
final UniformArray<UniformVec3Slot> vec3Array = shader.getUniformVec3Array('uVec3Array');
final UniformArray<UniformVec4Slot> vec4Array = shader.getUniformVec4Array('uVec4Array');
+ final UniformArray<UniformMat2Slot> mat2Array = shader.getUniformMat2Array('uMat2Array');
+ final UniformArray<UniformMat3Slot> mat3Array = shader.getUniformMat3Array('uMat3Array');
+ final UniformArray<UniformMat4Slot> mat4Array = shader.getUniformMat4Array('uMat4Array');
- var colorOffset = 4;
+ var colorOffset = 13;
for (var i = 0; i < 10; ++i) {
floatArray[i].set(cpuColors[colorOffset++].r);
@@ -526,6 +1125,53 @@
);
++colorOffset;
}
+ for (var i = 0; i < 10; ++i) {
+ mat2Array[i].set(
+ cpuColors[colorOffset].r,
+ cpuColors[colorOffset].g,
+ cpuColors[colorOffset + 1].r,
+ cpuColors[colorOffset + 1].g,
+ );
+ colorOffset += 2;
+ }
+ for (var i = 0; i < 10; ++i) {
+ mat3Array[i].set(
+ cpuColors[colorOffset].r,
+ cpuColors[colorOffset].g,
+ cpuColors[colorOffset].b,
+ cpuColors[colorOffset + 1].r,
+ cpuColors[colorOffset + 1].g,
+ cpuColors[colorOffset + 1].b,
+ cpuColors[colorOffset + 2].r,
+ cpuColors[colorOffset + 2].g,
+ cpuColors[colorOffset + 2].b,
+ );
+ colorOffset += 3;
+ }
+ for (var i = 0; i < 10; ++i) {
+ mat4Array[i].set(
+ cpuColors[colorOffset].r,
+ cpuColors[colorOffset].g,
+ cpuColors[colorOffset].b,
+ cpuColors[colorOffset].a,
+
+ cpuColors[colorOffset + 1].r,
+ cpuColors[colorOffset + 1].g,
+ cpuColors[colorOffset + 1].b,
+ cpuColors[colorOffset + 1].a,
+
+ cpuColors[colorOffset + 2].r,
+ cpuColors[colorOffset + 2].g,
+ cpuColors[colorOffset + 2].b,
+ cpuColors[colorOffset + 2].a,
+
+ cpuColors[colorOffset + 3].r,
+ cpuColors[colorOffset + 3].g,
+ cpuColors[colorOffset + 3].b,
+ cpuColors[colorOffset + 3].a,
+ );
+ colorOffset += 4;
+ }
_expectShaderRendersBarcode(shader, cpuColors);
});
});