-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] add herustic for ignoring coverage limit w/ image filters. #55030
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,13 @@ | |
|
||
namespace impeller { | ||
|
||
namespace { | ||
bool SizeDifferenceUnderThreshold(Size a, Size b, Scalar threshold) { | ||
return (std::abs(a.width - b.width) / b.width) < threshold && | ||
(std::abs(a.height - b.height) / b.height) < threshold; | ||
} | ||
} // namespace | ||
|
||
std::optional<Rect> ComputeSaveLayerCoverage( | ||
const Rect& content_coverage, | ||
const Matrix& effect_transform, | ||
|
@@ -64,8 +71,27 @@ std::optional<Rect> ComputeSaveLayerCoverage( | |
return source_coverage_limit; | ||
} | ||
|
||
return coverage.TransformBounds(effect_transform) | ||
.Intersection(source_coverage_limit.value()); | ||
// Trimming the content coverage by the coverage limit can reduce memory | ||
// coverage. limit can reduce memory bandwith. But in cases where there are | ||
// animated matrix filters, such as in the framework's zoom transition, the | ||
// changing scale values continually change the source_coverage_limit. | ||
// Intersecting the source_coverage_limit with the coverage may result in | ||
// slightly different texture sizes each frame of the animation. This leads | ||
// to non-optimal allocation patterns as differently sized textures cannot | ||
// be reused. Hence the following herustic: If the coverage is within a | ||
// semi-arbitrary percentage of the intersected coverage, then just use the | ||
// transformed coverage. In other cases, use the intersection. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about going further and using surfaces that are rounded up to a tile size or some other quantization size? Would we be able to reuse the surfaces? Some thought would need to be taken with kClamp/repeat/mirror tile modes, though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OOh, that is a good idea. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can the clamp/repeat modes restrict themselves to a coordinate sample not on the edge? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We control the input UVs for all of our image filters, so should be able to easily (tm) restrict the input range. |
||
auto transformed_coverage = coverage.TransformBounds(effect_transform); | ||
auto intersected_coverage = | ||
transformed_coverage.Intersection(source_coverage_limit.value()); | ||
if (intersected_coverage.has_value() && | ||
SizeDifferenceUnderThreshold(transformed_coverage.GetSize(), | ||
intersected_coverage->GetSize(), 0.2)) { | ||
// Returning the transformed coverage is always correct, it just may | ||
// be larger than the clip area or onscreen texture. | ||
return transformed_coverage; | ||
} | ||
return intersected_coverage; | ||
} | ||
|
||
// If the input coverage is maximum, just return the coverage limit that | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double phrase.