mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
153 lines
4.5 KiB
Dart
153 lines
4.5 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'rendering_tester.dart';
|
|
|
|
void main() {
|
|
test('nested repaint boundaries - smoke test', () {
|
|
RenderOpacity a, b, c;
|
|
a = RenderOpacity(
|
|
opacity: 1.0,
|
|
child: RenderRepaintBoundary(
|
|
child: b = RenderOpacity(
|
|
opacity: 1.0,
|
|
child: RenderRepaintBoundary(
|
|
child: c = RenderOpacity(
|
|
opacity: 1.0,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
layout(a, phase: EnginePhase.flushSemantics);
|
|
c.opacity = 0.9;
|
|
pumpFrame(phase: EnginePhase.flushSemantics);
|
|
a.opacity = 0.8;
|
|
c.opacity = 0.8;
|
|
pumpFrame(phase: EnginePhase.flushSemantics);
|
|
a.opacity = 0.7;
|
|
b.opacity = 0.7;
|
|
c.opacity = 0.7;
|
|
pumpFrame(phase: EnginePhase.flushSemantics);
|
|
});
|
|
|
|
test('Repaint boundary can get new parent after markNeedsCompositingBitsUpdate', () {
|
|
// Regression test for https://github.com/flutter/flutter/issues/24029.
|
|
|
|
final RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();
|
|
layout(repaintBoundary, phase: EnginePhase.flushSemantics);
|
|
|
|
repaintBoundary.markNeedsCompositingBitsUpdate();
|
|
|
|
renderer.renderView.child = null;
|
|
final RenderPadding padding = RenderPadding(
|
|
padding: const EdgeInsets.all(50),
|
|
);
|
|
renderer.renderView.child = padding;
|
|
padding.child = repaintBoundary;
|
|
pumpFrame(phase: EnginePhase.flushSemantics);
|
|
});
|
|
|
|
test('Framework creates an OffsetLayer for a repaint boundary', () {
|
|
final _TestRepaintBoundary repaintBoundary = _TestRepaintBoundary();
|
|
final RenderOpacity opacity = RenderOpacity(
|
|
opacity: 1.0,
|
|
child: repaintBoundary,
|
|
);
|
|
layout(opacity, phase: EnginePhase.flushSemantics);
|
|
expect(repaintBoundary.debugLayer, isA<OffsetLayer>());
|
|
});
|
|
|
|
test('Framework does not create an OffsetLayer for a non-repaint boundary', () {
|
|
final _TestNonCompositedBox nonCompositedBox = _TestNonCompositedBox();
|
|
final RenderOpacity opacity = RenderOpacity(
|
|
opacity: 1.0,
|
|
child: nonCompositedBox,
|
|
);
|
|
layout(opacity, phase: EnginePhase.flushSemantics);
|
|
expect(nonCompositedBox.debugLayer, null);
|
|
});
|
|
|
|
test('Framework allows a non-repaint boundary to create own layer', () {
|
|
final _TestCompositedBox compositedBox = _TestCompositedBox();
|
|
final RenderOpacity opacity = RenderOpacity(
|
|
opacity: 1.0,
|
|
child: compositedBox,
|
|
);
|
|
layout(opacity, phase: EnginePhase.flushSemantics);
|
|
expect(compositedBox.debugLayer, isA<OpacityLayer>());
|
|
});
|
|
|
|
test('Framework ensures repaint boundary layer is not overwritten', () {
|
|
final _TestRepaintBoundaryThatOverwritesItsLayer faultyRenderObject = _TestRepaintBoundaryThatOverwritesItsLayer();
|
|
final RenderOpacity opacity = RenderOpacity(
|
|
opacity: 1.0,
|
|
child: faultyRenderObject,
|
|
);
|
|
|
|
late FlutterErrorDetails error;
|
|
layout(opacity, phase: EnginePhase.flushSemantics, onErrors: () {
|
|
error = renderer.takeFlutterErrorDetails()!;
|
|
});
|
|
expect('${error.exception}', contains('Attempted to set a layer to a repaint boundary render object.'));
|
|
});
|
|
}
|
|
|
|
// A plain render object that's a repaint boundary.
|
|
class _TestRepaintBoundary extends RenderBox {
|
|
@override
|
|
bool get isRepaintBoundary => true;
|
|
|
|
@override
|
|
void performLayout() {
|
|
size = constraints.smallest;
|
|
}
|
|
}
|
|
|
|
// A render object that's a repaint boundary and (incorrectly) creates its own layer.
|
|
class _TestRepaintBoundaryThatOverwritesItsLayer extends RenderBox {
|
|
@override
|
|
bool get isRepaintBoundary => true;
|
|
|
|
@override
|
|
void performLayout() {
|
|
size = constraints.smallest;
|
|
}
|
|
|
|
@override
|
|
void paint(PaintingContext context, Offset offset) {
|
|
layer = OpacityLayer(alpha: 50);
|
|
}
|
|
}
|
|
|
|
// A render object that's neither a repaint boundary nor creates its own layer.
|
|
class _TestNonCompositedBox extends RenderBox {
|
|
@override
|
|
bool get isRepaintBoundary => false;
|
|
|
|
@override
|
|
void performLayout() {
|
|
size = constraints.smallest;
|
|
}
|
|
}
|
|
|
|
// A render object that's not a repaint boundary but creates its own layer.
|
|
class _TestCompositedBox extends RenderBox {
|
|
@override
|
|
bool get isRepaintBoundary => false;
|
|
|
|
@override
|
|
void performLayout() {
|
|
size = constraints.smallest;
|
|
}
|
|
|
|
@override
|
|
void paint(PaintingContext context, Offset offset) {
|
|
layer = OpacityLayer(alpha: 50);
|
|
}
|
|
}
|