Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/ui/dart_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
17 changes: 17 additions & 0 deletions lib/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4314,13 +4314,27 @@ 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// 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
/// 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.
///
/// Use of this method may result in poor performance with the Impeller backend.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be careful about describing something as having poor performance with no refernce point. I've seen users go to extensive lengths to avoid invoking apis that have warnings like this, sometimes exceeding the original performance cost.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM, removed this.

void setSampler(int index, ImageShader sampler) {
assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this');
_setSampler(index, sampler);
Expand All @@ -4341,6 +4355,9 @@ class FragmentShader extends Shader {
@FfiNative<Handle Function(Handle, Handle, Handle, Handle)>('ReusableFragmentShader::Create')
external Float32List _constructor(FragmentProgram program, int floatUniforms, int samplerUniforms);

@FfiNative<Void Function(Pointer<Void>, Handle, Handle)>('ReusableFragmentShader::SetImageSampler')
external void _setImageSampler(int index, Image sampler);

@FfiNative<Void Function(Pointer<Void>, Handle, Handle)>('ReusableFragmentShader::SetSampler')
external void _setSampler(int index, ImageShader sampler);

Expand Down
23 changes: 23 additions & 0 deletions lib/ui/painting/fragment_shader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#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"
Expand Down Expand Up @@ -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<uint64_t>::FromDart(index_handle);
CanvasImage* image =
tonic::DartConverter<CanvasImage*>::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<DlImageColorSource>(
image->image(), DlTileMode::kClamp, DlTileMode::kClamp,
DlImageSampling::kNearestNeighbor, nullptr);

auto* uniform_floats =
reinterpret_cast<float*>(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<uint64_t>::FromDart(index_handle);
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/painting/fragment_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down