Commit 1a292ff6 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Hint that painting shadows are complex (#5000)

Previously, we considered them one operation in the compositor, which didn't
trigger caching. Now we have a way to explicitly hint that the compositor
should cache a layer.
parent 243b72bb
......@@ -1200,6 +1200,9 @@ class BoxDecoration extends Decoration {
);
}
@override
bool get isComplex => boxShadow != null;
/// Linearly interpolate between two box decorations.
///
/// Interpolates each parameter of the box decoration separately.
......
......@@ -44,6 +44,9 @@ abstract class Decoration {
/// to inset the children so as to not overlap the frame.
EdgeInsets get padding => null;
/// Whether this decoration is complex enough to benefit from caching its painting.
bool get isComplex => false;
/// Linearly interpolates from [a] to [this].
Decoration lerpFrom(Decoration a, double t) => this;
......
......@@ -114,9 +114,24 @@ class PictureLayer extends Layer {
/// The picture's coodinate system matches this layer's coodinate system
ui.Picture picture;
/// Hints that the painting in this layer is complex and would benefit from
/// caching.
///
/// If this hint is not set, the compositor will apply its own heuristics to
/// decide whether the this layer is complex enough to benefit from caching.
bool isComplexHint = false;
/// Hints that the painting in this layer is likely to change next frame.
///
/// This hint tells the compositor not to cache this layer because the cache
/// will not be used in the future. If this hint is not set, the compositor
/// will apply its own heuristics to decide whether this layer is likely to be
/// reused in the future.
bool willChangeHint = false;
@override
void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
builder.addPicture(layerOffset, picture);
builder.addPicture(layerOffset, picture, isComplexHint: isComplexHint, willChangeHint: willChangeHint);
}
}
......
......@@ -192,6 +192,26 @@ class PaintingContext {
static final Paint _disableAntialias = new Paint()..isAntiAlias = false;
/// Hints that the painting in the current layer is complex and would benefit
/// from caching.
///
/// If this hint is not set, the compositor will apply its own heuristics to
/// decide whether the current layer is complex enough to benefit from
/// caching.
void setIsComplexHint() {
_currentLayer?.isComplexHint = true;
}
/// Hints that the painting in the current layer is likely to change next frame.
///
/// This hint tells the compositor not to cache the current layer because the
/// cache will not be used in the future. If this hint is not set, the
/// compositor will apply its own heuristics to decide whether the current
/// layer is likely to be reused in the future.
void setWillChangeHint() {
_currentLayer?.willChangeHint = true;
}
/// Adds a performance overlay to the scene.
///
/// * `offset` is the offset from the origin of the canvas' coordinate system
......
......@@ -1172,11 +1172,17 @@ class RenderDecoratedBox extends RenderProxyBox {
assert(size.height != null);
_painter ??= _decoration.createBoxPainter(markNeedsPaint);
final ImageConfiguration filledConfiguration = configuration.copyWith(size: size);
if (position == DecorationPosition.background)
if (position == DecorationPosition.background) {
_painter.paint(context.canvas, offset, filledConfiguration);
if (decoration.isComplex)
context.setIsComplexHint();
}
super.paint(context, offset);
if (position == DecorationPosition.foreground)
if (position == DecorationPosition.foreground) {
_painter.paint(context.canvas, offset, filledConfiguration);
if (decoration.isComplex)
context.setIsComplexHint();
}
}
@override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment