mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Add 1 pixel border to snapshots of Contents (flutter/engine#42277)
Everything in Impeller is theoretically treated as if being drawn to layers of infinite size. Without this change, there's a coverage leak that occurs in some filters due to the customizable sampling mode. I should be able to get rid of this 1 pixel padding by refactoring the way we do sampling in the filter inputs (we already have most of this infrastructure in place), but this is a correct, safe, and not-that-expensive solution for the time being.
This commit is contained in:
parent
3a4677a6d7
commit
d6a717c958
@ -64,13 +64,20 @@ std::optional<Snapshot> Contents::RenderToSnapshot(
|
||||
bool msaa_enabled,
|
||||
const std::string& label) const {
|
||||
auto coverage = GetCoverage(entity);
|
||||
if (coverage_limit.has_value()) {
|
||||
coverage = coverage->Intersection(*coverage_limit);
|
||||
}
|
||||
if (!coverage.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Pad Contents snapshots with 1 pixel borders to ensure correct sampling
|
||||
// behavior. Not doing so results in a coverage leak for filters that support
|
||||
// customizing the input sampling mode. Snapshots of contents should be
|
||||
// theoretically treated as infinite size just like layers.
|
||||
coverage = coverage->Expand(1);
|
||||
|
||||
if (coverage_limit.has_value()) {
|
||||
coverage = coverage->Intersection(*coverage_limit);
|
||||
}
|
||||
|
||||
auto texture = renderer.MakeSubpass(
|
||||
label, ISize::Ceil(coverage->size),
|
||||
[&contents = *this, &entity, &coverage](const ContentContext& renderer,
|
||||
|
||||
@ -1783,6 +1783,34 @@ TEST(GeometryTest, RectMakePointBounds) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(GeometryTest, RectExpand) {
|
||||
{
|
||||
auto a = Rect::MakeLTRB(100, 100, 200, 200);
|
||||
auto b = a.Expand(1);
|
||||
auto expected = Rect::MakeLTRB(99, 99, 201, 201);
|
||||
ASSERT_RECT_NEAR(b, expected);
|
||||
}
|
||||
{
|
||||
auto a = Rect::MakeLTRB(100, 100, 200, 200);
|
||||
auto b = a.Expand(-1);
|
||||
auto expected = Rect::MakeLTRB(101, 101, 199, 199);
|
||||
ASSERT_RECT_NEAR(b, expected);
|
||||
}
|
||||
|
||||
{
|
||||
auto a = Rect::MakeLTRB(100, 100, 200, 200);
|
||||
auto b = a.Expand(1, 2, 3, 4);
|
||||
auto expected = Rect::MakeLTRB(99, 98, 203, 204);
|
||||
ASSERT_RECT_NEAR(b, expected);
|
||||
}
|
||||
{
|
||||
auto a = Rect::MakeLTRB(100, 100, 200, 200);
|
||||
auto b = a.Expand(-1, -2, -3, -4);
|
||||
auto expected = Rect::MakeLTRB(101, 102, 197, 196);
|
||||
ASSERT_RECT_NEAR(b, expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(GeometryTest, RectGetPositive) {
|
||||
{
|
||||
Rect r{100, 200, 300, 400};
|
||||
|
||||
@ -252,6 +252,24 @@ struct TRect {
|
||||
return TRect(origin.x + offset.x, origin.y + offset.y, size.width,
|
||||
size.height);
|
||||
}
|
||||
|
||||
/// @brief Returns a rectangle with expanded edges. Negative expansion
|
||||
/// results in shrinking.
|
||||
constexpr TRect<T> Expand(T left, T top, T right, T bottom) {
|
||||
return TRect(origin.x - left, //
|
||||
origin.y - top, //
|
||||
size.width + left + right, //
|
||||
size.height + top + bottom);
|
||||
}
|
||||
|
||||
/// @brief Returns a rectangle with expanded edges in all directions.
|
||||
/// Negative expansion results in shrinking.
|
||||
constexpr TRect<T> Expand(T amount) {
|
||||
return TRect(origin.x - amount, //
|
||||
origin.y - amount, //
|
||||
size.width + amount * 2, //
|
||||
size.height + amount * 2);
|
||||
}
|
||||
};
|
||||
|
||||
using Rect = TRect<Scalar>;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user