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

Commit 9c51b1b

Browse files
committed
[Impeller] Fix sampling management problems
1 parent 6a2de77 commit 9c51b1b

12 files changed

+78
-28
lines changed

impeller/display_list/display_list_dispatcher.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ static impeller::SamplerDescriptor ToSamplerDescriptor(
136136
desc.label = "Nearest Sampler";
137137
break;
138138
case flutter::DlImageSampling::kLinear:
139+
// Impeller doesn't support cubic sampling, but linear is closer to correct
140+
// than nearest for this case.
141+
case flutter::DlImageSampling::kCubic:
139142
desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear;
140143
desc.label = "Linear Sampler";
141144
break;
@@ -144,8 +147,6 @@ static impeller::SamplerDescriptor ToSamplerDescriptor(
144147
desc.mip_filter = impeller::MipFilter::kLinear;
145148
desc.label = "Mipmap Linear Sampler";
146149
break;
147-
default:
148-
break;
149150
}
150151
return desc;
151152
}

impeller/entity/contents/contents.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Contents::StencilCoverage Contents::GetStencilCoverage(
4141
std::optional<Snapshot> Contents::RenderToSnapshot(
4242
const ContentContext& renderer,
4343
const Entity& entity,
44+
const std::optional<SamplerDescriptor>& sampler_descriptor,
4445
bool msaa_enabled) const {
4546
auto coverage = GetCoverage(entity);
4647
if (!coverage.has_value()) {
@@ -64,8 +65,15 @@ std::optional<Snapshot> Contents::RenderToSnapshot(
6465
return std::nullopt;
6566
}
6667

67-
return Snapshot{.texture = texture,
68-
.transform = Matrix::MakeTranslation(coverage->origin)};
68+
auto snapshot = Snapshot{
69+
.texture = texture,
70+
.transform = Matrix::MakeTranslation(coverage->origin),
71+
};
72+
if (sampler_descriptor.has_value()) {
73+
snapshot.sampler_descriptor = sampler_descriptor.value();
74+
}
75+
76+
return snapshot;
6977
}
7078

7179
bool Contents::ShouldRender(const Entity& entity,

impeller/entity/contents/contents.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "flutter/fml/macros.h"
1212
#include "impeller/geometry/rect.h"
13+
#include "impeller/renderer/sampler_descriptor.h"
1314
#include "impeller/renderer/snapshot.h"
1415
#include "impeller/renderer/texture.h"
1516

@@ -61,6 +62,7 @@ class Contents {
6162
virtual std::optional<Snapshot> RenderToSnapshot(
6263
const ContentContext& renderer,
6364
const Entity& entity,
65+
const std::optional<SamplerDescriptor>& sampler_descriptor = std::nullopt,
6466
bool msaa_enabled = true) const;
6567

6668
virtual bool ShouldRender(const Entity& entity,

impeller/entity/contents/filters/blend_filter_contents.cc

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "impeller/entity/contents/solid_color_contents.h"
1515
#include "impeller/entity/entity.h"
1616
#include "impeller/geometry/path_builder.h"
17+
#include "impeller/renderer/formats.h"
1718
#include "impeller/renderer/render_pass.h"
1819
#include "impeller/renderer/sampler_library.h"
1920

@@ -107,8 +108,9 @@ static std::optional<Snapshot> AdvancedBlend(
107108

108109
typename FS::BlendInfo blend_info;
109110

110-
auto sampler = renderer.GetContext()->GetSamplerLibrary()->GetSampler({});
111-
FS::BindTextureSamplerDst(cmd, dst_snapshot->texture, sampler);
111+
auto dst_sampler = renderer.GetContext()->GetSamplerLibrary()->GetSampler(
112+
dst_snapshot->sampler_descriptor);
113+
FS::BindTextureSamplerDst(cmd, dst_snapshot->texture, dst_sampler);
112114
blend_info.dst_y_coord_scale = dst_snapshot->texture->GetYCoordScale();
113115
blend_info.dst_input_alpha = absorb_opacity ? dst_snapshot->opacity : 1.0;
114116

@@ -118,10 +120,12 @@ static std::optional<Snapshot> AdvancedBlend(
118120
// This texture will not be sampled from due to the color factor. But
119121
// this is present so that validation doesn't trip on a missing
120122
// binding.
121-
FS::BindTextureSamplerSrc(cmd, dst_snapshot->texture, sampler);
123+
FS::BindTextureSamplerSrc(cmd, dst_snapshot->texture, dst_sampler);
122124
} else {
125+
auto src_sampler = renderer.GetContext()->GetSamplerLibrary()->GetSampler(
126+
src_snapshot->sampler_descriptor);
123127
blend_info.color_factor = 0;
124-
FS::BindTextureSamplerSrc(cmd, src_snapshot->texture, sampler);
128+
FS::BindTextureSamplerSrc(cmd, src_snapshot->texture, src_sampler);
125129
blend_info.src_y_coord_scale = src_snapshot->texture->GetYCoordScale();
126130
}
127131
auto blend_uniform = host_buffer.EmplaceUniform(blend_info);
@@ -145,7 +149,10 @@ static std::optional<Snapshot> AdvancedBlend(
145149

146150
return Snapshot{.texture = out_texture,
147151
.transform = Matrix::MakeTranslation(coverage.origin),
148-
.sampler_descriptor = dst_snapshot->sampler_descriptor,
152+
// Since we absorbed the transform of the inputs and used the
153+
// respective snapshot sampling modes when blending, pass on
154+
// the default NN clamp sampler.
155+
.sampler_descriptor = {},
149156
.opacity = (absorb_opacity ? 1.0f : dst_snapshot->opacity) *
150157
alpha.value_or(1.0)};
151158
}
@@ -168,8 +175,6 @@ static std::optional<Snapshot> PipelineBlend(
168175
RenderPass& pass) {
169176
auto& host_buffer = pass.GetTransientsBuffer();
170177

171-
auto sampler = renderer.GetContext()->GetSamplerLibrary()->GetSampler({});
172-
173178
Command cmd;
174179
cmd.label = "Pipeline Blend Filter";
175180
auto options = OptionsFromPass(pass);
@@ -183,6 +188,8 @@ static std::optional<Snapshot> PipelineBlend(
183188
return false;
184189
}
185190

191+
auto sampler = renderer.GetContext()->GetSamplerLibrary()->GetSampler(
192+
input->sampler_descriptor);
186193
FS::BindTextureSamplerSrc(cmd, input->texture, sampler);
187194

188195
auto size = input->texture->GetSize();
@@ -262,13 +269,14 @@ static std::optional<Snapshot> PipelineBlend(
262269
}
263270
out_texture->SetLabel("Pipeline Blend Filter Texture");
264271

265-
return Snapshot{
266-
.texture = out_texture,
267-
.transform = Matrix::MakeTranslation(coverage.origin),
268-
.sampler_descriptor =
269-
inputs[0]->GetSnapshot(renderer, entity)->sampler_descriptor,
270-
.opacity = (absorb_opacity ? 1.0f : dst_snapshot->opacity) *
271-
alpha.value_or(1.0)};
272+
return Snapshot{.texture = out_texture,
273+
.transform = Matrix::MakeTranslation(coverage.origin),
274+
// Since we absorbed the transform of the inputs and used the
275+
// respective snapshot sampling modes when blending, pass on
276+
// the default NN clamp sampler.
277+
.sampler_descriptor = {},
278+
.opacity = (absorb_opacity ? 1.0f : dst_snapshot->opacity) *
279+
alpha.value_or(1.0)};
272280
}
273281

274282
#define BLEND_CASE(mode) \
@@ -346,6 +354,7 @@ std::optional<Snapshot> BlendFilterContents::RenderFilter(
346354
foreground_color_, GetAbsorbOpacity(),
347355
GetAlpha());
348356
}
357+
349358
FML_UNREACHABLE();
350359
}
351360

impeller/entity/contents/filters/filter_contents.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ std::optional<Rect> FilterContents::GetFilterCoverage(
237237
std::optional<Snapshot> FilterContents::RenderToSnapshot(
238238
const ContentContext& renderer,
239239
const Entity& entity,
240+
const std::optional<SamplerDescriptor>& sampler_descriptor,
240241
bool msaa_enabled) const {
241242
Entity entity_with_local_transform = entity;
242243
entity_with_local_transform.SetTransformation(

impeller/entity/contents/filters/filter_contents.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class FilterContents : public Contents {
119119
std::optional<Snapshot> RenderToSnapshot(
120120
const ContentContext& renderer,
121121
const Entity& entity,
122+
const std::optional<SamplerDescriptor>& sampler_descriptor = std::nullopt,
122123
bool msaa_enabled = true) const override;
123124

124125
virtual Matrix GetLocalTransform(const Matrix& parent_transform) const;

impeller/entity/contents/filters/inputs/contents_filter_input.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "impeller/entity/contents/filters/inputs/contents_filter_input.h"
66

7+
#include <optional>
78
#include <utility>
89

910
namespace impeller {
@@ -22,7 +23,8 @@ std::optional<Snapshot> ContentsFilterInput::GetSnapshot(
2223
const ContentContext& renderer,
2324
const Entity& entity) const {
2425
if (!snapshot_.has_value()) {
25-
snapshot_ = contents_->RenderToSnapshot(renderer, entity, msaa_enabled_);
26+
snapshot_ = contents_->RenderToSnapshot(renderer, entity, std::nullopt,
27+
msaa_enabled_);
2628
}
2729
return snapshot_;
2830
}

impeller/entity/contents/texture_contents.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ std::optional<Rect> TextureContents::GetCoverage(const Entity& entity) const {
6767
std::optional<Snapshot> TextureContents::RenderToSnapshot(
6868
const ContentContext& renderer,
6969
const Entity& entity,
70+
const std::optional<SamplerDescriptor>& sampler_descriptor,
7071
bool msaa_enabled) const {
7172
auto bounds = path_.GetBoundingBox();
7273
if (!bounds.has_value()) {
@@ -78,14 +79,16 @@ std::optional<Snapshot> TextureContents::RenderToSnapshot(
7879
if (is_rect_ && source_rect_ == Rect::MakeSize(texture_->GetSize()) &&
7980
(opacity_ >= 1 - kEhCloseEnough || defer_applying_opacity_)) {
8081
auto scale = Vector2(bounds->size / Size(texture_->GetSize()));
81-
return Snapshot{.texture = texture_,
82-
.transform = entity.GetTransformation() *
83-
Matrix::MakeTranslation(bounds->origin) *
84-
Matrix::MakeScale(scale),
85-
.sampler_descriptor = sampler_descriptor_,
86-
.opacity = opacity_};
82+
return Snapshot{
83+
.texture = texture_,
84+
.transform = entity.GetTransformation() *
85+
Matrix::MakeTranslation(bounds->origin) *
86+
Matrix::MakeScale(scale),
87+
.sampler_descriptor = sampler_descriptor.value_or(sampler_descriptor_),
88+
.opacity = opacity_};
8789
}
88-
return Contents::RenderToSnapshot(renderer, entity);
90+
return Contents::RenderToSnapshot(
91+
renderer, entity, sampler_descriptor.value_or(sampler_descriptor_));
8992
}
9093

9194
bool TextureContents::Render(const ContentContext& renderer,

impeller/entity/contents/texture_contents.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class TextureContents final : public Contents {
5555
std::optional<Snapshot> RenderToSnapshot(
5656
const ContentContext& renderer,
5757
const Entity& entity,
58+
const std::optional<SamplerDescriptor>& sampler_descriptor = std::nullopt,
5859
bool msaa_enabled = true) const override;
5960

6061
// |Contents|

impeller/renderer/sampler_descriptor.cc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,19 @@
33
// found in the LICENSE file.
44

55
#include "impeller/renderer/sampler_descriptor.h"
6+
#include "fml/logging.h"
67

78
namespace impeller {
89

9-
//
10+
SamplerDescriptor::SamplerDescriptor() = default;
11+
12+
SamplerDescriptor::SamplerDescriptor(std::string label,
13+
MinMagFilter min_filter,
14+
MinMagFilter mag_filter,
15+
MipFilter mip_filter)
16+
: min_filter(min_filter),
17+
mag_filter(mag_filter),
18+
mip_filter(mip_filter),
19+
label(std::move(label)) {}
1020

1121
} // namespace impeller

impeller/renderer/sampler_descriptor.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ struct SamplerDescriptor final : public Comparable<SamplerDescriptor> {
2626

2727
std::string label = "NN Clamp Sampler";
2828

29+
SamplerDescriptor();
30+
31+
SamplerDescriptor(std::string label,
32+
MinMagFilter min_filter,
33+
MinMagFilter mag_filter,
34+
MipFilter mip_filter);
35+
2936
// Comparable<SamplerDescriptor>
3037
std::size_t GetHash() const override {
3138
return fml::HashCombine(min_filter, mag_filter, mip_filter,

impeller/renderer/snapshot.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "flutter/fml/macros.h"
1212
#include "impeller/geometry/matrix.h"
1313
#include "impeller/geometry/rect.h"
14+
#include "impeller/renderer/formats.h"
1415
#include "impeller/renderer/sampler_descriptor.h"
1516
#include "impeller/renderer/texture.h"
1617

@@ -25,7 +26,11 @@ struct Snapshot {
2526
/// The transform that should be applied to this texture for rendering.
2627
Matrix transform;
2728

28-
SamplerDescriptor sampler_descriptor;
29+
SamplerDescriptor sampler_descriptor =
30+
SamplerDescriptor("Default Snapshot Sampler",
31+
MinMagFilter::kLinear,
32+
MinMagFilter::kLinear,
33+
MipFilter::kLinear);
2934

3035
Scalar opacity = 1.0f;
3136

0 commit comments

Comments
 (0)