Add setImageSampler (for replacing setSampler) (flutter/engine#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
This commit is contained in:
Brandon DeRosier 2022-11-21 20:24:14 -08:00 committed by GitHub
parent 986101452a
commit a640b398e2
7 changed files with 58 additions and 0 deletions

View File

@ -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) \

View File

@ -4314,6 +4314,18 @@ class FragmentShader extends Shader {
_floats[index] = value;
}
/// Sets the sampler uniform at [index] to [image].
///
/// 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
/// results will be undefined.
void setImageSampler(int index, Image image) {
assert(!debugDisposed, 'Tried to access uniforms on a disposed Shader: $this');
_setImageSampler(index, image._image);
}
/// Sets the sampler uniform at [index] to [sampler].
///
/// The index provided to setSampler is the index of the sampler uniform defined
@ -4341,6 +4353,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);

View File

@ -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"
@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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,15 @@ class CkFragmentShader implements ui.FragmentShader {
floats[index] = value;
}
@override
void setImageSampler(int index, ui.Image image) {
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());
setFloat(lastFloatIndex + 2 * index + 1, sampler.imageHeight.toDouble());
}
@override
void setSampler(int index, ui.ImageShader sampler) {
samplers[index] = (sampler as CkShader).skiaObject;

View File

@ -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.');