mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Fix the transform and geometry criteria for an optimization in TiledTextureContents (flutter/engine#47341)
TiledTextureContents::RenderToSnapshot should only create a snapshot directly from the texture if the geometry is an axis-aligned rectangle. Fixes https://github.com/flutter/flutter/issues/136504
This commit is contained in:
parent
5316d75378
commit
6ef260d4b5
@ -3781,5 +3781,55 @@ TEST_P(AiksTest, EmptySaveLayerRendersWithClear) {
|
||||
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
|
||||
}
|
||||
|
||||
TEST_P(AiksTest, BlurredRectangleWithShader) {
|
||||
Canvas canvas;
|
||||
canvas.Scale(GetContentScale());
|
||||
|
||||
auto paint_lines = [&canvas](Scalar dx, Scalar dy, Paint paint) {
|
||||
auto draw_line = [&canvas, &paint](Point a, Point b) {
|
||||
canvas.DrawPath(PathBuilder{}.AddLine(a, b).TakePath(), paint);
|
||||
};
|
||||
paint.stroke_width = 5;
|
||||
paint.style = Paint::Style::kStroke;
|
||||
draw_line(Point(dx + 100, dy + 100), Point(dx + 200, dy + 200));
|
||||
draw_line(Point(dx + 100, dy + 200), Point(dx + 200, dy + 100));
|
||||
draw_line(Point(dx + 150, dy + 100), Point(dx + 200, dy + 150));
|
||||
draw_line(Point(dx + 100, dy + 150), Point(dx + 150, dy + 200));
|
||||
};
|
||||
|
||||
AiksContext renderer(GetContext(), nullptr);
|
||||
Canvas recorder_canvas;
|
||||
for (int x = 0; x < 5; ++x) {
|
||||
for (int y = 0; y < 5; ++y) {
|
||||
Rect rect = Rect::MakeXYWH(x * 20, y * 20, 20, 20);
|
||||
Paint paint{.color =
|
||||
((x + y) & 1) == 0 ? Color::Yellow() : Color::Blue()};
|
||||
recorder_canvas.DrawRect(rect, paint);
|
||||
}
|
||||
}
|
||||
Picture picture = recorder_canvas.EndRecordingAsPicture();
|
||||
std::shared_ptr<Texture> texture =
|
||||
picture.ToImage(renderer, ISize{100, 100})->GetTexture();
|
||||
|
||||
ColorSource image_source = ColorSource::MakeImage(
|
||||
texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {});
|
||||
std::shared_ptr<ImageFilter> blur_filter = ImageFilter::MakeBlur(
|
||||
Sigma(5), Sigma(5), FilterContents::BlurStyle::kNormal,
|
||||
Entity::TileMode::kDecal);
|
||||
canvas.DrawRect(Rect::MakeLTRB(0, 0, 300, 600),
|
||||
Paint{.color = Color::DarkGreen()});
|
||||
canvas.DrawRect(Rect::MakeLTRB(100, 100, 200, 200),
|
||||
Paint{.color_source = image_source});
|
||||
canvas.DrawRect(Rect::MakeLTRB(300, 0, 600, 600),
|
||||
Paint{.color = Color::Red()});
|
||||
canvas.DrawRect(
|
||||
Rect::MakeLTRB(400, 100, 500, 200),
|
||||
Paint{.color_source = image_source, .image_filter = blur_filter});
|
||||
paint_lines(0, 300, Paint{.color_source = image_source});
|
||||
paint_lines(300, 300,
|
||||
Paint{.color_source = image_source, .image_filter = blur_filter});
|
||||
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
|
||||
@ -202,10 +202,18 @@ std::optional<Snapshot> TiledTextureContents::RenderToSnapshot(
|
||||
const std::optional<SamplerDescriptor>& sampler_descriptor,
|
||||
bool msaa_enabled,
|
||||
const std::string& label) const {
|
||||
if (GetInverseEffectTransform().IsIdentity()) {
|
||||
if (GetInverseEffectTransform().IsIdentity() &&
|
||||
GetGeometry()->IsAxisAlignedRect()) {
|
||||
auto coverage = GetCoverage(entity);
|
||||
if (!coverage.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto scale = Vector2(coverage->size / Size(texture_->GetSize()));
|
||||
|
||||
return Snapshot{
|
||||
.texture = texture_,
|
||||
.transform = entity.GetTransformation(),
|
||||
.transform = Matrix::MakeTranslation(coverage->origin) *
|
||||
Matrix::MakeScale(scale),
|
||||
.sampler_descriptor = sampler_descriptor.value_or(sampler_descriptor_),
|
||||
.opacity = GetOpacityFactor(),
|
||||
};
|
||||
|
||||
@ -147,4 +147,8 @@ bool Geometry::CoversArea(const Matrix& transform, const Rect& rect) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Geometry::IsAxisAlignedRect() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -101,6 +101,8 @@ class Geometry {
|
||||
/// given `rect`. May return `false` in many undetected cases where
|
||||
/// the transformed geometry does in fact cover the `rect`.
|
||||
virtual bool CoversArea(const Matrix& transform, const Rect& rect) const;
|
||||
|
||||
virtual bool IsAxisAlignedRect() const;
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -55,4 +55,8 @@ bool RectGeometry::CoversArea(const Matrix& transform, const Rect& rect) const {
|
||||
return coverage.Contains(rect);
|
||||
}
|
||||
|
||||
bool RectGeometry::IsAxisAlignedRect() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -17,6 +17,9 @@ class RectGeometry : public Geometry {
|
||||
// |Geometry|
|
||||
bool CoversArea(const Matrix& transform, const Rect& rect) const override;
|
||||
|
||||
// |Geometry|
|
||||
bool IsAxisAlignedRect() const override;
|
||||
|
||||
private:
|
||||
// |Geometry|
|
||||
GeometryResult GetPositionBuffer(const ContentContext& renderer,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user