Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit eba7ecd

Browse files
authored
Add setImageSampler (for replacing setSampler) (#37821)
* Add setImageSampler (for replacing setSampler) * Includes * Remove deprecation tag, just in case there are roll problems * Remove comment * Fix comment * Add setImageSampler for canvaskit * Remove arg * Fix conversion * Float64List * final... * Pass along the engine handle
1 parent c3645c3 commit eba7ecd

File tree

7 files changed

+58
-0
lines changed

7 files changed

+58
-0
lines changed

lib/ui/dart_ui.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ typedef CanvasPath Path;
174174
V(EngineLayer, dispose, 1) \
175175
V(FragmentProgram, initFromAsset, 2) \
176176
V(ReusableFragmentShader, Dispose, 1) \
177+
V(ReusableFragmentShader, SetImageSampler, 3) \
177178
V(ReusableFragmentShader, SetSampler, 3) \
178179
V(ReusableFragmentShader, ValidateSamplers, 1) \
179180
V(Gradient, initLinear, 6) \

lib/ui/painting.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4314,6 +4314,18 @@ class FragmentShader extends Shader {
43144314
_floats[index] = value;
43154315
}
43164316

4317+
/// Sets the sampler uniform at [index] to [image].
4318+
///
4319+
/// The index provided to setImageSampler is the index of the sampler uniform defined
4320+
/// in the fragment program, excluding all non-sampler uniforms.
4321+
///
4322+
/// All the sampler uniforms that a shader expects must be provided or the
4323+
/// results will be undefined.
4324+
void setImageSampler(int index, Image image) {
4325+
assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this');
4326+
_setImageSampler(index, image._image);
4327+
}
4328+
43174329
/// Sets the sampler uniform at [index] to [sampler].
43184330
///
43194331
/// The index provided to setSampler is the index of the sampler uniform defined
@@ -4341,6 +4353,9 @@ class FragmentShader extends Shader {
43414353
@FfiNative<Handle Function(Handle, Handle, Handle, Handle)>('ReusableFragmentShader::Create')
43424354
external Float32List _constructor(FragmentProgram program, int floatUniforms, int samplerUniforms);
43434355

4356+
@FfiNative<Void Function(Pointer<Void>, Handle, Handle)>('ReusableFragmentShader::SetImageSampler')
4357+
external void _setImageSampler(int index, _Image sampler);
4358+
43444359
@FfiNative<Void Function(Pointer<Void>, Handle, Handle)>('ReusableFragmentShader::SetSampler')
43454360
external void _setSampler(int index, ImageShader sampler);
43464361

lib/ui/painting/fragment_shader.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#include "flutter/lib/ui/painting/fragment_shader.h"
99

10+
#include "flutter/display_list/display_list_color_source.h"
11+
#include "flutter/display_list/display_list_tile_mode.h"
1012
#include "flutter/lib/ui/dart_wrapper.h"
1113
#include "flutter/lib/ui/painting/fragment_program.h"
1214
#include "flutter/lib/ui/ui_dart_state.h"
@@ -61,6 +63,27 @@ bool ReusableFragmentShader::ValidateSamplers() {
6163
return true;
6264
}
6365

66+
void ReusableFragmentShader::SetImageSampler(Dart_Handle index_handle,
67+
Dart_Handle image_handle) {
68+
uint64_t index = tonic::DartConverter<uint64_t>::FromDart(index_handle);
69+
CanvasImage* image =
70+
tonic::DartConverter<CanvasImage*>::FromDart(image_handle);
71+
if (index >= samplers_.size()) {
72+
Dart_ThrowException(tonic::ToDart("Sampler index out of bounds"));
73+
}
74+
75+
// TODO(115794): Once the DlImageSampling enum is replaced, expose the
76+
// sampling options as a new default parameter for users.
77+
samplers_[index] = std::make_shared<DlImageColorSource>(
78+
image->image(), DlTileMode::kClamp, DlTileMode::kClamp,
79+
DlImageSampling::kNearestNeighbor, nullptr);
80+
81+
auto* uniform_floats =
82+
reinterpret_cast<float*>(uniform_data_->writable_data());
83+
uniform_floats[float_count_ + 2 * index] = image->width();
84+
uniform_floats[float_count_ + 2 * index + 1] = image->height();
85+
}
86+
6487
void ReusableFragmentShader::SetSampler(Dart_Handle index_handle,
6588
Dart_Handle sampler_handle) {
6689
uint64_t index = tonic::DartConverter<uint64_t>::FromDart(index_handle);

lib/ui/painting/fragment_shader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class ReusableFragmentShader : public Shader {
3434
Dart_Handle float_count,
3535
Dart_Handle sampler_count);
3636

37+
void SetImageSampler(Dart_Handle index, Dart_Handle image);
38+
3739
void SetSampler(Dart_Handle index, Dart_Handle sampler);
3840

3941
bool ValidateSamplers();

lib/web_ui/lib/painting.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,8 @@ abstract class FragmentProgram {
818818
abstract class FragmentShader implements Shader {
819819
void setFloat(int index, double value);
820820

821+
void setImageSampler(int index, Image image);
822+
821823
void setSampler(int index, ImageShader sampler);
822824

823825
@override

lib/web_ui/lib/src/engine/canvaskit/painting.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'dart:typed_data';
88
import 'package:ui/ui.dart' as ui;
99

1010
import '../color_filter.dart';
11+
import '../vector_math.dart';
1112
import 'canvaskit_api.dart';
1213
import 'color_filter.dart';
1314
import 'image_filter.dart';
@@ -476,6 +477,15 @@ class CkFragmentShader implements ui.FragmentShader {
476477
floats[index] = value;
477478
}
478479

480+
@override
481+
void setImageSampler(int index, ui.Image image) {
482+
final ui.ImageShader sampler = ui.ImageShader(image, ui.TileMode.clamp,
483+
ui.TileMode.clamp, toMatrix64(Matrix4.identity().storage));
484+
samplers[index] = (sampler as CkShader).skiaObject;
485+
setFloat(lastFloatIndex + 2 * index, (sampler as CkImageShader).imageWidth.toDouble());
486+
setFloat(lastFloatIndex + 2 * index + 1, sampler.imageHeight.toDouble());
487+
}
488+
479489
@override
480490
void setSampler(int index, ui.ImageShader sampler) {
481491
samplers[index] = (sampler as CkShader).skiaObject;

lib/web_ui/lib/src/engine/html/painting.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ class HtmlFragmentShader implements ui.FragmentShader {
302302
throw UnsupportedError('FragmentShader is not supported for the HTML renderer.');
303303
}
304304

305+
@override
306+
void setImageSampler(int index, ui.Image image) {
307+
throw UnsupportedError('FragmentShader is not supported for the HTML renderer.');
308+
}
309+
305310
@override
306311
void setSampler(int index, ui.ImageShader sampler) {
307312
throw UnsupportedError('FragmentShader is not supported for the HTML renderer.');

0 commit comments

Comments
 (0)