Unverified Commit e331dcda authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[framework] make transform with filterQuality a rpb (#116792)

* [framework] make transform with filterQuality a rpb

* fix tests

* ++
parent 15939b47
......@@ -2430,7 +2430,7 @@ class RenderTransform extends RenderProxyBox {
return;
}
_origin = value;
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
......@@ -2452,7 +2452,7 @@ class RenderTransform extends RenderProxyBox {
return;
}
_alignment = value;
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
......@@ -2467,10 +2467,13 @@ class RenderTransform extends RenderProxyBox {
return;
}
_textDirection = value;
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
@override
bool get isRepaintBoundary => alwaysNeedsCompositing;
@override
bool get alwaysNeedsCompositing => child != null && _filterQuality != null;
......@@ -2495,7 +2498,7 @@ class RenderTransform extends RenderProxyBox {
return;
}
_transform = Matrix4.copy(value);
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
......@@ -2513,48 +2516,48 @@ class RenderTransform extends RenderProxyBox {
if (didNeedCompositing != alwaysNeedsCompositing) {
markNeedsCompositingBitsUpdate();
}
markNeedsPaint();
markNeedsCompositedLayerUpdate();
}
/// Sets the transform to the identity matrix.
void setIdentity() {
_transform!.setIdentity();
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
/// Concatenates a rotation about the x axis into the transform.
void rotateX(double radians) {
_transform!.rotateX(radians);
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
/// Concatenates a rotation about the y axis into the transform.
void rotateY(double radians) {
_transform!.rotateY(radians);
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
/// Concatenates a rotation about the z axis into the transform.
void rotateZ(double radians) {
_transform!.rotateZ(radians);
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
/// Concatenates a translation by (x, y, z) into the transform.
void translate(double x, [ double y = 0.0, double z = 0.0 ]) {
_transform!.translate(x, y, z);
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
/// Concatenates a scale into the transform.
void scale(double x, [ double? y, double? z ]) {
_transform!.scale(x, y, z);
markNeedsPaint();
markNeedsCompositedLayerUpdate();
markNeedsSemanticsUpdate();
}
......@@ -2603,51 +2606,46 @@ class RenderTransform extends RenderProxyBox {
);
}
@override
OffsetLayer updateCompositedLayer({required covariant ImageFilterLayer? oldLayer}) {
final ImageFilterLayer layer = oldLayer ?? ImageFilterLayer();
layer.imageFilter = ui.ImageFilter.matrix(
_effectiveTransform!.storage,
filterQuality: filterQuality!
);
return layer;
}
@override
void paint(PaintingContext context, Offset offset) {
if (child != null) {
final Matrix4 transform = _effectiveTransform!;
if (filterQuality == null) {
final Offset? childOffset = MatrixUtils.getAsTranslation(transform);
if (childOffset == null) {
// if the matrix is singular the children would be compressed to a line or
// single point, instead short-circuit and paint nothing.
final double det = transform.determinant();
if (det == 0 || !det.isFinite) {
layer = null;
return;
}
layer = context.pushTransform(
needsCompositing,
offset,
transform,
super.paint,
oldLayer: layer is TransformLayer ? layer as TransformLayer? : null,
);
} else {
super.paint(context, offset + childOffset);
layer = null;
}
} else {
final Matrix4 effectiveTransform = Matrix4.translationValues(offset.dx, offset.dy, 0.0)
..multiply(transform)..translate(-offset.dx, -offset.dy);
final ui.ImageFilter filter = ui.ImageFilter.matrix(
effectiveTransform.storage,
filterQuality: filterQuality!,
);
if (layer is ImageFilterLayer) {
final ImageFilterLayer filterLayer = layer! as ImageFilterLayer;
filterLayer.imageFilter = filter;
} else {
layer = ImageFilterLayer(imageFilter: filter);
}
context.pushLayer(layer!, super.paint, offset);
assert(() {
layer!.debugCreator = debugCreator;
return true;
}());
}
if (child == null) {
return;
}
if (isRepaintBoundary) {
return super.paint(context, offset);
}
final Matrix4 transform = _effectiveTransform!;
final Offset? childOffset = MatrixUtils.getAsTranslation(transform);
if (childOffset != null) {
super.paint(context, offset + childOffset);
layer = null;
return;
}
// if the matrix is singular the children would be compressed to a line or
// single point, instead short-circuit and paint nothing.
final double det = transform.determinant();
if (det == 0 || !det.isFinite) {
layer = null;
return;
}
layer = context.pushTransform(
needsCompositing,
offset,
transform,
super.paint,
oldLayer: layer is TransformLayer ? layer as TransformLayer? : null,
);
}
@override
......
......@@ -35,6 +35,35 @@ void main() {
expect(RenderTestObject.paintCount, 1);
});
testWidgets('Transform with FilterQuality avoids repainting child as it animates', (WidgetTester tester) async {
RenderTestObject.paintCount = 0;
await tester.pumpWidget(
Container(
color: Colors.red,
child: Transform.translate(
offset: const Offset(5.0, 10.0),
filterQuality: FilterQuality.low,
child: const TestWidget(),
),
)
);
expect(RenderTestObject.paintCount, 1);
await tester.pumpWidget(
Container(
color: Colors.red,
child: Transform.translate(
offset: const Offset(25.0, 0.0),
filterQuality: FilterQuality.low,
child: const TestWidget(),
),
)
);
expect(RenderTestObject.paintCount, 1);
});
}
class TestWidget extends SingleChildRenderObjectWidget {
......
......@@ -616,7 +616,7 @@ void main() {
moreOrLessEquals(0.7071067811865476), moreOrLessEquals(0.7071067811865475), 0.0, 0.0,
moreOrLessEquals(-0.7071067811865475), moreOrLessEquals(0.7071067811865476), 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
moreOrLessEquals(329.28932188134524), moreOrLessEquals(-194.97474683058329), 0.0, 1.0,
moreOrLessEquals(50), moreOrLessEquals(-20.710678118654755), 0.0, 1.0,
]);
});
......
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