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 { ...@@ -1200,6 +1200,9 @@ class BoxDecoration extends Decoration {
); );
} }
@override
bool get isComplex => boxShadow != null;
/// Linearly interpolate between two box decorations. /// Linearly interpolate between two box decorations.
/// ///
/// Interpolates each parameter of the box decoration separately. /// Interpolates each parameter of the box decoration separately.
......
...@@ -44,6 +44,9 @@ abstract class Decoration { ...@@ -44,6 +44,9 @@ abstract class Decoration {
/// to inset the children so as to not overlap the frame. /// to inset the children so as to not overlap the frame.
EdgeInsets get padding => null; 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]. /// Linearly interpolates from [a] to [this].
Decoration lerpFrom(Decoration a, double t) => this; Decoration lerpFrom(Decoration a, double t) => this;
......
...@@ -114,9 +114,24 @@ class PictureLayer extends Layer { ...@@ -114,9 +114,24 @@ class PictureLayer extends Layer {
/// The picture's coodinate system matches this layer's coodinate system /// The picture's coodinate system matches this layer's coodinate system
ui.Picture picture; 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 @override
void addToScene(ui.SceneBuilder builder, Offset layerOffset) { 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 { ...@@ -192,6 +192,26 @@ class PaintingContext {
static final Paint _disableAntialias = new Paint()..isAntiAlias = false; 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. /// Adds a performance overlay to the scene.
/// ///
/// * `offset` is the offset from the origin of the canvas' coordinate system /// * `offset` is the offset from the origin of the canvas' coordinate system
......
...@@ -1172,11 +1172,17 @@ class RenderDecoratedBox extends RenderProxyBox { ...@@ -1172,11 +1172,17 @@ class RenderDecoratedBox extends RenderProxyBox {
assert(size.height != null); assert(size.height != null);
_painter ??= _decoration.createBoxPainter(markNeedsPaint); _painter ??= _decoration.createBoxPainter(markNeedsPaint);
final ImageConfiguration filledConfiguration = configuration.copyWith(size: size); final ImageConfiguration filledConfiguration = configuration.copyWith(size: size);
if (position == DecorationPosition.background) if (position == DecorationPosition.background) {
_painter.paint(context.canvas, offset, filledConfiguration); _painter.paint(context.canvas, offset, filledConfiguration);
if (decoration.isComplex)
context.setIsComplexHint();
}
super.paint(context, offset); super.paint(context, offset);
if (position == DecorationPosition.foreground) if (position == DecorationPosition.foreground) {
_painter.paint(context.canvas, offset, filledConfiguration); _painter.paint(context.canvas, offset, filledConfiguration);
if (decoration.isComplex)
context.setIsComplexHint();
}
} }
@override @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