From f1daacf796d4707a0a6da727024161c2e691df8f Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 14:47:31 -0800 Subject: [PATCH 01/11] Add setImageSampler (for replacing setSampler) --- lib/ui/dart_ui.cc | 1 + lib/ui/painting.dart | 18 ++++++++++++++++++ lib/ui/painting/fragment_shader.cc | 23 +++++++++++++++++++++++ lib/ui/painting/fragment_shader.h | 2 ++ 4 files changed, 44 insertions(+) diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 5199821389311..b9488181966ae 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -174,6 +174,7 @@ typedef CanvasPath Path; V(EngineLayer, dispose, 1) \ V(FragmentProgram, initFromAsset, 2) \ V(ReusableFragmentShader, Dispose, 1) \ + V(ReusableFragmentShader, SetImageSampler, 3) \ V(ReusableFragmentShader, SetSampler, 3) \ V(ReusableFragmentShader, ValidateSamplers, 1) \ V(Gradient, initLinear, 6) \ diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 307ac9ca7affa..3c5faf51af8a7 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -4314,6 +4314,18 @@ class FragmentShader extends Shader { _floats[index] = value; } + /// Sets the sampler uniform at [index] to [image]. + /// + /// The index provided to setSampler is the index of the sampler uniform defined + /// in the fragment program, excluding all non-sampler uniforms. + /// + /// All the sampler uniforms that a shader expects must be provided or the + /// results will be undefined. + void setImageSampler(int index, Image image) { + assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this'); + _setImageSampler(index, image); + } + /// Sets the sampler uniform at [index] to [sampler]. /// /// The index provided to setSampler is the index of the sampler uniform defined @@ -4321,6 +4333,9 @@ class FragmentShader extends Shader { /// /// All the sampler uniforms that a shader expects must be provided or the /// results will be undefined. + /// + /// Use of this method may result in poor performance with the Impeller backend. + @Deprecated('Use setImageSampler instead.') void setSampler(int index, ImageShader sampler) { assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this'); _setSampler(index, sampler); @@ -4341,6 +4356,9 @@ class FragmentShader extends Shader { @FfiNative('ReusableFragmentShader::Create') external Float32List _constructor(FragmentProgram program, int floatUniforms, int samplerUniforms); + @FfiNative, Handle, Handle)>('ReusableFragmentShader::SetImageSampler') + external void _setImageSampler(int index, Image sampler); + @FfiNative, Handle, Handle)>('ReusableFragmentShader::SetSampler') external void _setSampler(int index, ImageShader sampler); diff --git a/lib/ui/painting/fragment_shader.cc b/lib/ui/painting/fragment_shader.cc index 38f62ef3d507e..b40c4c93844ac 100644 --- a/lib/ui/painting/fragment_shader.cc +++ b/lib/ui/painting/fragment_shader.cc @@ -5,6 +5,8 @@ #include #include +#include "display_list/display_list_color_source.h" +#include "display_list/display_list_tile_mode.h" #include "flutter/lib/ui/painting/fragment_shader.h" #include "flutter/lib/ui/dart_wrapper.h" @@ -61,6 +63,27 @@ bool ReusableFragmentShader::ValidateSamplers() { return true; } +void ReusableFragmentShader::SetImageSampler(Dart_Handle index_handle, + Dart_Handle image_handle) { + uint64_t index = tonic::DartConverter::FromDart(index_handle); + CanvasImage* image = + tonic::DartConverter::FromDart(image_handle); + if (index >= samplers_.size()) { + Dart_ThrowException(tonic::ToDart("Sampler index out of bounds")); + } + + // TODO(115794): Once the DlImageSampling enum is replaced, expose the + // sampling options as a new default parameter for users. + samplers_[index] = std::make_shared( + image->image(), DlTileMode::kClamp, DlTileMode::kClamp, + DlImageSampling::kNearestNeighbor, nullptr); + + auto* uniform_floats = + reinterpret_cast(uniform_data_->writable_data()); + uniform_floats[float_count_ + 2 * index] = image->width(); + uniform_floats[float_count_ + 2 * index + 1] = image->height(); +} + void ReusableFragmentShader::SetSampler(Dart_Handle index_handle, Dart_Handle sampler_handle) { uint64_t index = tonic::DartConverter::FromDart(index_handle); diff --git a/lib/ui/painting/fragment_shader.h b/lib/ui/painting/fragment_shader.h index 5b948e80dea0c..36dea2c61c711 100644 --- a/lib/ui/painting/fragment_shader.h +++ b/lib/ui/painting/fragment_shader.h @@ -34,6 +34,8 @@ class ReusableFragmentShader : public Shader { Dart_Handle float_count, Dart_Handle sampler_count); + void SetImageSampler(Dart_Handle index, Dart_Handle image); + void SetSampler(Dart_Handle index, Dart_Handle sampler); bool ValidateSamplers(); From ecb29be12defb203beaa1955079d5e46995897df Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 14:49:54 -0800 Subject: [PATCH 02/11] Includes --- lib/ui/painting/fragment_shader.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ui/painting/fragment_shader.cc b/lib/ui/painting/fragment_shader.cc index b40c4c93844ac..3a87c260f3d6a 100644 --- a/lib/ui/painting/fragment_shader.cc +++ b/lib/ui/painting/fragment_shader.cc @@ -5,10 +5,10 @@ #include #include -#include "display_list/display_list_color_source.h" -#include "display_list/display_list_tile_mode.h" #include "flutter/lib/ui/painting/fragment_shader.h" +#include "flutter/display_list/display_list_color_source.h" +#include "flutter/display_list/display_list_tile_mode.h" #include "flutter/lib/ui/dart_wrapper.h" #include "flutter/lib/ui/painting/fragment_program.h" #include "flutter/lib/ui/ui_dart_state.h" From 4190467bfb65c3ba286cf559a3d7e73782c713e0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 15:07:58 -0800 Subject: [PATCH 03/11] Remove deprecation tag, just in case there are roll problems --- lib/ui/painting.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 3c5faf51af8a7..5c447b030cee7 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -4335,7 +4335,6 @@ class FragmentShader extends Shader { /// results will be undefined. /// /// Use of this method may result in poor performance with the Impeller backend. - @Deprecated('Use setImageSampler instead.') void setSampler(int index, ImageShader sampler) { assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this'); _setSampler(index, sampler); From 5a5021f45448702456378438a85a99d0535953b0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 15:48:49 -0800 Subject: [PATCH 04/11] Remove comment --- lib/ui/painting.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 5c447b030cee7..03c3010565e91 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -4333,8 +4333,6 @@ class FragmentShader extends Shader { /// /// All the sampler uniforms that a shader expects must be provided or the /// results will be undefined. - /// - /// Use of this method may result in poor performance with the Impeller backend. void setSampler(int index, ImageShader sampler) { assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this'); _setSampler(index, sampler); From 6e9c9a00a1a88fa4154b25d577fe39eaedf1daa0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 15:50:35 -0800 Subject: [PATCH 05/11] Fix comment --- lib/ui/painting.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 03c3010565e91..2cb740cfe2539 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -4316,7 +4316,7 @@ class FragmentShader extends Shader { /// Sets the sampler uniform at [index] to [image]. /// - /// The index provided to setSampler is the index of the sampler uniform defined + /// The index provided to setImageSampler is the index of the sampler uniform defined /// in the fragment program, excluding all non-sampler uniforms. /// /// All the sampler uniforms that a shader expects must be provided or the From e43e5f55beced06562a16f123f8ddddc599f1bd6 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 17:28:43 -0800 Subject: [PATCH 06/11] Add setImageSampler for canvaskit --- lib/web_ui/lib/painting.dart | 2 ++ lib/web_ui/lib/src/engine/canvaskit/painting.dart | 14 ++++++++++++++ lib/web_ui/lib/src/engine/html/painting.dart | 5 +++++ 3 files changed, 21 insertions(+) diff --git a/lib/web_ui/lib/painting.dart b/lib/web_ui/lib/painting.dart index 7a0d7439cb8ff..445b5f79dbb50 100644 --- a/lib/web_ui/lib/painting.dart +++ b/lib/web_ui/lib/painting.dart @@ -818,6 +818,8 @@ abstract class FragmentProgram { abstract class FragmentShader implements Shader { void setFloat(int index, double value); + void setImageSampler(int index, Image image); + void setSampler(int index, ImageShader sampler); @override diff --git a/lib/web_ui/lib/src/engine/canvaskit/painting.dart b/lib/web_ui/lib/src/engine/canvaskit/painting.dart index b9a7296207c7e..3bdffadeedc99 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/painting.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/painting.dart @@ -8,6 +8,7 @@ import 'dart:typed_data'; import 'package:ui/ui.dart' as ui; import '../color_filter.dart'; +import '../vector_math.dart'; import 'canvaskit_api.dart'; import 'color_filter.dart'; import 'image_filter.dart'; @@ -476,6 +477,19 @@ class CkFragmentShader implements ui.FragmentShader { floats[index] = value; } + @override + void setImageSampler(int index, ui.Image image) { + ui.ImageShader sampler = ui.ImageShader( + image, + ui.TileMode.clamp, + ui.TileMode.clamp, + Float32List.fromList(Matrix4.identity().storage), + null); + samplers[index] = (sampler as CkShader).skiaObject; + setFloat(lastFloatIndex + 2 * index, (sampler as CkImageShader).imageWidth.toDouble()); + setFloat(lastFloatIndex + 2 * index + 1, sampler.imageHeight.toDouble()); + } + @override void setSampler(int index, ui.ImageShader sampler) { samplers[index] = (sampler as CkShader).skiaObject; diff --git a/lib/web_ui/lib/src/engine/html/painting.dart b/lib/web_ui/lib/src/engine/html/painting.dart index dc3ccdc4f63a7..22408fa188e38 100644 --- a/lib/web_ui/lib/src/engine/html/painting.dart +++ b/lib/web_ui/lib/src/engine/html/painting.dart @@ -302,6 +302,11 @@ class HtmlFragmentShader implements ui.FragmentShader { throw UnsupportedError('FragmentShader is not supported for the HTML renderer.'); } + @override + void setImageSampler(int index, ui.Image image) { + throw UnsupportedError('FragmentShader is not supported for the HTML renderer.'); + } + @override void setSampler(int index, ui.ImageShader sampler) { throw UnsupportedError('FragmentShader is not supported for the HTML renderer.'); From f56bfed534b8aaf6c77f1767ae7ef3c52f94304b Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 17:34:36 -0800 Subject: [PATCH 07/11] Remove arg --- lib/web_ui/lib/src/engine/canvaskit/painting.dart | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/painting.dart b/lib/web_ui/lib/src/engine/canvaskit/painting.dart index 3bdffadeedc99..278d72927d0f9 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/painting.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/painting.dart @@ -479,12 +479,8 @@ class CkFragmentShader implements ui.FragmentShader { @override void setImageSampler(int index, ui.Image image) { - ui.ImageShader sampler = ui.ImageShader( - image, - ui.TileMode.clamp, - ui.TileMode.clamp, - Float32List.fromList(Matrix4.identity().storage), - null); + ui.ImageShader sampler = ui.ImageShader(image, ui.TileMode.clamp, + ui.TileMode.clamp, Float32List.fromList(Matrix4.identity().storage)); samplers[index] = (sampler as CkShader).skiaObject; setFloat(lastFloatIndex + 2 * index, (sampler as CkImageShader).imageWidth.toDouble()); setFloat(lastFloatIndex + 2 * index + 1, sampler.imageHeight.toDouble()); From 0a353bbdc49e5056c2c42a191600744a1b2083c5 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 17:45:08 -0800 Subject: [PATCH 08/11] Fix conversion --- lib/web_ui/lib/src/engine/canvaskit/painting.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/painting.dart b/lib/web_ui/lib/src/engine/canvaskit/painting.dart index 278d72927d0f9..14afed9c43d24 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/painting.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/painting.dart @@ -480,7 +480,7 @@ class CkFragmentShader implements ui.FragmentShader { @override void setImageSampler(int index, ui.Image image) { ui.ImageShader sampler = ui.ImageShader(image, ui.TileMode.clamp, - ui.TileMode.clamp, Float32List.fromList(Matrix4.identity().storage)); + ui.TileMode.clamp, Matrix4.identity().storage); samplers[index] = (sampler as CkShader).skiaObject; setFloat(lastFloatIndex + 2 * index, (sampler as CkImageShader).imageWidth.toDouble()); setFloat(lastFloatIndex + 2 * index + 1, sampler.imageHeight.toDouble()); From 0109a0d965d1faba6e49acf857c524cd92de0ae9 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 17:55:39 -0800 Subject: [PATCH 09/11] Float64List --- lib/web_ui/lib/src/engine/canvaskit/painting.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/painting.dart b/lib/web_ui/lib/src/engine/canvaskit/painting.dart index 14afed9c43d24..0988a9c19c005 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/painting.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/painting.dart @@ -480,7 +480,7 @@ class CkFragmentShader implements ui.FragmentShader { @override void setImageSampler(int index, ui.Image image) { ui.ImageShader sampler = ui.ImageShader(image, ui.TileMode.clamp, - ui.TileMode.clamp, Matrix4.identity().storage); + ui.TileMode.clamp, toMatrix64(Matrix4.identity().storage)); samplers[index] = (sampler as CkShader).skiaObject; setFloat(lastFloatIndex + 2 * index, (sampler as CkImageShader).imageWidth.toDouble()); setFloat(lastFloatIndex + 2 * index + 1, sampler.imageHeight.toDouble()); From 0d00c73cd8c6bd5d5fa71d11086510f6f5e75a01 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 18:09:10 -0800 Subject: [PATCH 10/11] final... --- lib/web_ui/lib/src/engine/canvaskit/painting.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/painting.dart b/lib/web_ui/lib/src/engine/canvaskit/painting.dart index 0988a9c19c005..bb586ef545f1a 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/painting.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/painting.dart @@ -479,7 +479,7 @@ class CkFragmentShader implements ui.FragmentShader { @override void setImageSampler(int index, ui.Image image) { - ui.ImageShader sampler = ui.ImageShader(image, ui.TileMode.clamp, + final ui.ImageShader sampler = ui.ImageShader(image, ui.TileMode.clamp, ui.TileMode.clamp, toMatrix64(Matrix4.identity().storage)); samplers[index] = (sampler as CkShader).skiaObject; setFloat(lastFloatIndex + 2 * index, (sampler as CkImageShader).imageWidth.toDouble()); From da6f1cb4323e7a1437d8cb425e34ec4676c4a577 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 21 Nov 2022 18:38:24 -0800 Subject: [PATCH 11/11] Pass along the engine handle --- lib/ui/painting.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 2cb740cfe2539..23d4ac32e66f6 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -4323,7 +4323,7 @@ class FragmentShader extends Shader { /// results will be undefined. void setImageSampler(int index, Image image) { assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this'); - _setImageSampler(index, image); + _setImageSampler(index, image._image); } /// Sets the sampler uniform at [index] to [sampler]. @@ -4354,7 +4354,7 @@ class FragmentShader extends Shader { external Float32List _constructor(FragmentProgram program, int floatUniforms, int samplerUniforms); @FfiNative, Handle, Handle)>('ReusableFragmentShader::SetImageSampler') - external void _setImageSampler(int index, Image sampler); + external void _setImageSampler(int index, _Image sampler); @FfiNative, Handle, Handle)>('ReusableFragmentShader::SetSampler') external void _setSampler(int index, ImageShader sampler);