[Impeller] Make matrix image filter work as expected (flutter/engine#36193)

This commit is contained in:
ColdPaleLight 2022-09-21 16:46:59 +08:00 committed by GitHub
parent 77889be4d3
commit 020eeb67bd
6 changed files with 53 additions and 11 deletions

View File

@ -578,8 +578,10 @@ static std::optional<Paint::ImageFilterProc> ToImageFilterProc(
auto matrix_filter = filter->asMatrix();
FML_DCHECK(matrix_filter);
auto matrix = ToMatrix(matrix_filter->matrix());
return [matrix](FilterInput::Ref input, const Matrix& effect_transform) {
return FilterContents::MakeMatrixFilter(input, matrix);
auto desc = ToSamplerDescriptor(matrix_filter->sampling());
return [matrix, desc](FilterInput::Ref input,
const Matrix& effect_transform) {
return FilterContents::MakeMatrixFilter(input, matrix, desc);
};
break;
}

View File

@ -670,7 +670,9 @@ TEST_P(DisplayListTest, CanDrawWithMatrixFilter) {
flutter::DisplayListBuilder builder;
SkPaint paint;
builder.saveLayer(nullptr, nullptr);
if (enable_savelayer) {
builder.saveLayer(nullptr, nullptr);
}
{
auto content_scale = GetContentScale();
builder.scale(content_scale.x, content_scale.y);
@ -695,7 +697,8 @@ TEST_P(DisplayListTest, CanDrawWithMatrixFilter) {
builder.drawImage(DlImageImpeller::Make(boston), {},
flutter::DlImageSampling::kLinear, true);
}
if (enable_savelayer) {
builder.restore();
}
return builder.Build();

View File

@ -178,10 +178,12 @@ std::shared_ptr<FilterContents> FilterContents::MakeSrgbToLinearFilter(
std::shared_ptr<FilterContents> FilterContents::MakeMatrixFilter(
FilterInput::Ref input,
const Matrix& matrix) {
const Matrix& matrix,
const SamplerDescriptor& desc) {
auto filter = std::make_shared<MatrixFilterContents>();
filter->SetInputs({input});
filter->SetMatrix(matrix);
filter->SetSamplerDescriptor(desc);
return filter;
}

View File

@ -92,7 +92,8 @@ class FilterContents : public Contents {
static std::shared_ptr<FilterContents> MakeMatrixFilter(
FilterInput::Ref input,
const Matrix& matrix);
const Matrix& matrix,
const SamplerDescriptor& desc);
FilterContents();

View File

@ -14,9 +14,8 @@ void MatrixFilterContents::SetMatrix(Matrix matrix) {
matrix_ = matrix;
}
Matrix MatrixFilterContents::GetLocalTransform(
const Matrix& parent_transform) const {
return parent_transform.Invert() * matrix_ * parent_transform;
void MatrixFilterContents::SetSamplerDescriptor(SamplerDescriptor desc) {
sampler_descriptor_ = std::move(desc);
}
std::optional<Snapshot> MatrixFilterContents::RenderFilter(
@ -25,7 +24,36 @@ std::optional<Snapshot> MatrixFilterContents::RenderFilter(
const Entity& entity,
const Matrix& effect_transform,
const Rect& coverage) const {
return inputs[0]->GetSnapshot(renderer, entity);
auto snapshot = inputs[0]->GetSnapshot(renderer, entity);
if (!snapshot.has_value()) {
return std::nullopt;
}
snapshot->transform = entity.GetTransformation() * //
matrix_ * //
entity.GetTransformation().Invert() * //
snapshot->transform;
snapshot->sampler_descriptor = sampler_descriptor_;
return snapshot;
}
std::optional<Rect> MatrixFilterContents::GetFilterCoverage(
const FilterInput::Vector& inputs,
const Entity& entity,
const Matrix& effect_transform) const {
if (inputs.empty()) {
return std::nullopt;
}
auto coverage = inputs[0]->GetCoverage(entity);
if (!coverage.has_value()) {
return std::nullopt;
}
auto transform = inputs[0]->GetTransform(entity) * //
matrix_ * //
inputs[0]->GetTransform(entity).Invert();
return coverage->TransformBounds(transform);
}
} // namespace impeller

View File

@ -17,8 +17,13 @@ class MatrixFilterContents final : public FilterContents {
void SetMatrix(Matrix matrix);
void SetSamplerDescriptor(SamplerDescriptor desc);
// |FilterContents|
Matrix GetLocalTransform(const Matrix& parent_transform) const override;
std::optional<Rect> GetFilterCoverage(
const FilterInput::Vector& inputs,
const Entity& entity,
const Matrix& effect_transform) const override;
private:
// |FilterContents|
@ -30,6 +35,7 @@ class MatrixFilterContents final : public FilterContents {
const Rect& coverage) const override;
Matrix matrix_;
SamplerDescriptor sampler_descriptor_ = {};
FML_DISALLOW_COPY_AND_ASSIGN(MatrixFilterContents);
};