Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
025397ae
Unverified
Commit
025397ae
authored
Jun 25, 2021
by
Dan Field
Committed by
GitHub
Jun 25, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Release retained resources from layers/dispose pictures (#84740)
parent
1977ee75
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
631 additions
and
113 deletions
+631
-113
switch.dart
packages/flutter/lib/src/cupertino/switch.dart
+9
-3
text_selection_toolbar.dart
...ges/flutter/lib/src/cupertino/text_selection_toolbar.dart
+9
-3
input_decorator.dart
packages/flutter/lib/src/material/input_decorator.dart
+3
-5
animated_size.dart
packages/flutter/lib/src/rendering/animated_size.dart
+10
-4
editable.dart
packages/flutter/lib/src/rendering/editable.dart
+5
-4
flex.dart
packages/flutter/lib/src/rendering/flex.dart
+10
-4
flow.dart
packages/flutter/lib/src/rendering/flow.dart
+10
-4
layer.dart
packages/flutter/lib/src/rendering/layer.dart
+234
-4
list_wheel_viewport.dart
packages/flutter/lib/src/rendering/list_wheel_viewport.dart
+10
-4
object.dart
packages/flutter/lib/src/rendering/object.dart
+45
-32
platform_view.dart
packages/flutter/lib/src/rendering/platform_view.dart
+10
-4
rotated_box.dart
packages/flutter/lib/src/rendering/rotated_box.dart
+10
-4
shifted_box.dart
packages/flutter/lib/src/rendering/shifted_box.dart
+10
-4
stack.dart
packages/flutter/lib/src/rendering/stack.dart
+10
-4
viewport.dart
packages/flutter/lib/src/rendering/viewport.dart
+10
-4
wrap.dart
packages/flutter/lib/src/rendering/wrap.dart
+10
-4
overlay.dart
packages/flutter/lib/src/widgets/overlay.dart
+10
-4
single_child_scroll_view.dart
...ges/flutter/lib/src/widgets/single_child_scroll_view.dart
+10
-4
service_extensions_test.dart
...ages/flutter/test/foundation/service_extensions_test.dart
+1
-0
box_test.dart
packages/flutter/test/rendering/box_test.dart
+2
-2
debug_test.dart
packages/flutter/test/rendering/debug_test.dart
+4
-2
editable_test.dart
packages/flutter/test/rendering/editable_test.dart
+2
-2
flex_test.dart
packages/flutter/test/rendering/flex_test.dart
+2
-2
layers_test.dart
packages/flutter/test/rendering/layers_test.dart
+141
-2
object_paint_dispose_test.dart
...ges/flutter/test/rendering/object_paint_dispose_test.dart
+51
-0
rendering_tester.dart
packages/flutter/test/rendering/rendering_tester.dart
+0
-1
stack_test.dart
packages/flutter/test/rendering/stack_test.dart
+1
-1
wrap_test.dart
packages/flutter/test/rendering/wrap_test.dart
+2
-2
No files found.
packages/flutter/lib/src/cupertino/switch.dart
View file @
025397ae
...
...
@@ -524,12 +524,18 @@ class _RenderCupertinoSwitch extends RenderConstrainedBox {
thumbCenterY
+
CupertinoThumbPainter
.
radius
,
);
_clipRRectLayer
=
context
.
pushClipRRect
(
needsCompositing
,
Offset
.
zero
,
thumbBounds
,
trackRRect
,
(
PaintingContext
innerContext
,
Offset
offset
)
{
_clipRRectLayer
.
layer
=
context
.
pushClipRRect
(
needsCompositing
,
Offset
.
zero
,
thumbBounds
,
trackRRect
,
(
PaintingContext
innerContext
,
Offset
offset
)
{
const
CupertinoThumbPainter
.
switchThumb
().
paint
(
innerContext
.
canvas
,
thumbBounds
);
},
oldLayer:
_clipRRectLayer
);
},
oldLayer:
_clipRRectLayer
.
layer
);
}
ClipRRectLayer
?
_clipRRectLayer
;
final
LayerHandle
<
ClipRRectLayer
>
_clipRRectLayer
=
LayerHandle
<
ClipRRectLayer
>();
@override
void
dispose
()
{
_clipRRectLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
description
)
{
...
...
packages/flutter/lib/src/cupertino/text_selection_toolbar.dart
View file @
025397ae
...
...
@@ -289,19 +289,25 @@ class _RenderCupertinoTextSelectionToolbarShape extends RenderShiftedBox {
}
final
BoxParentData
childParentData
=
child
!.
parentData
!
as
BoxParentData
;
_clipPathLayer
=
context
.
pushClipPath
(
_clipPathLayer
.
layer
=
context
.
pushClipPath
(
needsCompositing
,
offset
+
childParentData
.
offset
,
Offset
.
zero
&
child
!.
size
,
_clipPath
(),
(
PaintingContext
innerContext
,
Offset
innerOffset
)
=>
innerContext
.
paintChild
(
child
!,
innerOffset
),
oldLayer:
_clipPathLayer
,
oldLayer:
_clipPathLayer
.
layer
,
);
}
ClipPathLayer
?
_clipPathLayer
;
final
LayerHandle
<
ClipPathLayer
>
_clipPathLayer
=
LayerHandle
<
ClipPathLayer
>()
;
Paint
?
_debugPaint
;
@override
void
dispose
()
{
_clipPathLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
void
debugPaintSize
(
PaintingContext
context
,
Offset
offset
)
{
assert
(()
{
...
...
packages/flutter/lib/src/material/input_decorator.dart
View file @
025397ae
...
...
@@ -1502,15 +1502,15 @@ class _RenderDecoration extends RenderBox {
_labelTransform
=
Matrix4
.
identity
()
..
translate
(
dx
,
labelOffset
.
dy
+
dy
)
..
scale
(
scale
);
_transformL
ayer
=
context
.
pushTransform
(
l
ayer
=
context
.
pushTransform
(
needsCompositing
,
offset
,
_labelTransform
!,
_paintLabel
,
oldLayer:
_transformLayer
,
oldLayer:
layer
as
TransformLayer
?
,
);
}
else
{
_transformL
ayer
=
null
;
l
ayer
=
null
;
}
doPaint
(
icon
);
...
...
@@ -1524,8 +1524,6 @@ class _RenderDecoration extends RenderBox {
doPaint
(
counter
);
}
TransformLayer
?
_transformLayer
;
@override
bool
hitTestSelf
(
Offset
position
)
=>
true
;
...
...
packages/flutter/lib/src/rendering/animated_size.dart
View file @
025397ae
...
...
@@ -327,19 +327,25 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
&&
_hasVisualOverflow
&&
clipBehavior
!=
Clip
.
none
)
{
final
Rect
rect
=
Offset
.
zero
&
size
;
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
rect
,
super
.
paint
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
else
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
super
.
paint
(
context
,
offset
);
}
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
}
packages/flutter/lib/src/rendering/editable.dart
View file @
025397ae
...
...
@@ -301,6 +301,7 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
_foregroundRenderObject
=
null
;
_backgroundRenderObject
?.
dispose
();
_backgroundRenderObject
=
null
;
_clipRectLayer
.
layer
=
null
;
_cachedBuiltInForegroundPainters
?.
dispose
();
_cachedBuiltInPainters
?.
dispose
();
super
.
dispose
();
...
...
@@ -4007,22 +4008,22 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
_computeTextMetricsIfNeeded
();
if
(
_hasVisualOverflow
&&
clipBehavior
!=
Clip
.
none
)
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
_paintContents
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
else
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
_paintContents
(
context
,
offset
);
}
_paintHandleLayers
(
context
,
getEndpointsForSelection
(
selection
!));
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>()
;
@override
Rect
?
describeApproximatePaintClip
(
RenderObject
child
)
=>
_hasVisualOverflow
?
Offset
.
zero
&
size
:
null
;
...
...
packages/flutter/lib/src/rendering/flex.dart
View file @
025397ae
...
...
@@ -1084,17 +1084,17 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
return
;
if
(
clipBehavior
==
Clip
.
none
)
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
defaultPaint
(
context
,
offset
);
}
else
{
// We have overflow and the clipBehavior isn't none. Clip it.
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
defaultPaint
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
...
...
@@ -1141,7 +1141,13 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
}());
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
Rect
?
describeApproximatePaintClip
(
RenderObject
child
)
=>
_hasOverflow
?
Offset
.
zero
&
size
:
null
;
...
...
packages/flutter/lib/src/rendering/flow.dart
View file @
025397ae
...
...
@@ -389,21 +389,27 @@ class RenderFlow extends RenderBox
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
clipBehavior
==
Clip
.
none
)
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
_paintWithDelegate
(
context
,
offset
);
}
else
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
_paintWithDelegate
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
bool
hitTestChildren
(
BoxHitTestResult
result
,
{
required
Offset
position
})
{
...
...
packages/flutter/lib/src/rendering/layer.dart
View file @
025397ae
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/rendering/list_wheel_viewport.dart
View file @
025397ae
...
...
@@ -785,22 +785,28 @@ class RenderListWheelViewport
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
childCount
>
0
)
{
if
(
_shouldClipAtCurrentOffset
()
&&
clipBehavior
!=
Clip
.
none
)
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
_paintVisibleChildren
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
else
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
_paintVisibleChildren
(
context
,
offset
);
}
}
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
/// Paints all children visible in the current viewport.
void
_paintVisibleChildren
(
PaintingContext
context
,
Offset
offset
)
{
...
...
packages/flutter/lib/src/rendering/object.dart
View file @
025397ae
...
...
@@ -117,30 +117,32 @@ class PaintingContext extends ClipContext {
);
return
true
;
}());
OffsetLayer
?
childLayer
=
child
.
_layer
as
OffsetLayer
?;
OffsetLayer
?
childLayer
=
child
.
_layer
Handle
.
layer
as
OffsetLayer
?;
if
(
childLayer
==
null
)
{
assert
(
debugAlsoPaintedParent
);
assert
(
child
.
_layerHandle
.
layer
==
null
);
// Not using the `layer` setter because the setter asserts that we not
// replace the layer for repaint boundaries. That assertion does not
// apply here because this is exactly the place designed to create a
// layer for repaint boundaries.
child
.
_layer
=
childLayer
=
OffsetLayer
();
final
OffsetLayer
layer
=
OffsetLayer
();
child
.
_layerHandle
.
layer
=
childLayer
=
layer
;
}
else
{
assert
(
debugAlsoPaintedParent
||
childLayer
.
attached
);
childLayer
.
removeAllChildren
();
}
assert
(
identical
(
childLayer
,
child
.
_layer
));
assert
(
child
.
_layer
is
OffsetLayer
);
assert
(
identical
(
childLayer
,
child
.
_layer
Handle
.
layer
));
assert
(
child
.
_layer
Handle
.
layer
is
OffsetLayer
);
assert
(()
{
child
.
_l
ayer
!.
debugCreator
=
child
.
debugCreator
??
child
.
runtimeType
;
child
L
ayer
!.
debugCreator
=
child
.
debugCreator
??
child
.
runtimeType
;
return
true
;
}());
childContext
??=
PaintingContext
(
child
.
_layer
!
,
child
.
paintBounds
);
childContext
??=
PaintingContext
(
child
Layer
,
child
.
paintBounds
);
child
.
_paintWithContext
(
childContext
,
Offset
.
zero
);
// Double-check that the paint method did not replace the layer (the first
// check is done in the [layer] setter itself).
assert
(
identical
(
childLayer
,
child
.
_layer
));
assert
(
identical
(
childLayer
,
child
.
_layer
Handle
.
layer
));
childContext
.
stopRecordingIfNeeded
();
}
...
...
@@ -209,14 +211,14 @@ class PaintingContext extends ClipContext {
includedParent:
true
,
includedChild:
false
,
);
child
.
_layer
!.
debugCreator
=
child
.
debugCreator
??
child
;
child
.
_layer
Handle
.
layer
!.
debugCreator
=
child
.
debugCreator
??
child
;
return
true
;
}());
}
assert
(
child
.
_layer
is
OffsetLayer
);
final
OffsetLayer
childOffsetLayer
=
child
.
_layer
!
as
OffsetLayer
;
assert
(
child
.
_layer
Handle
.
layer
is
OffsetLayer
);
final
OffsetLayer
childOffsetLayer
=
child
.
_layer
Handle
.
layer
!
as
OffsetLayer
;
childOffsetLayer
.
offset
=
offset
;
appendLayer
(
child
.
_layer
!
);
appendLayer
(
child
OffsetLayer
);
}
/// Adds a layer to the recording requiring that the recording is already
...
...
@@ -266,6 +268,7 @@ class PaintingContext extends ClipContext {
Canvas
get
canvas
{
if
(
_canvas
==
null
)
_startRecording
();
assert
(
_currentLayer
!=
null
);
return
_canvas
!;
}
...
...
@@ -391,6 +394,7 @@ class PaintingContext extends ClipContext {
stopRecordingIfNeeded
();
appendLayer
(
childLayer
);
final
PaintingContext
childContext
=
createChildContext
(
childLayer
,
childPaintBounds
??
estimatedBounds
);
painter
(
childContext
,
offset
);
childContext
.
stopRecordingIfNeeded
();
}
...
...
@@ -969,9 +973,9 @@ class PipelineOwner {
_nodesNeedingPaint
=
<
RenderObject
>[];
// Sort the dirty nodes in reverse order (deepest first).
for
(
final
RenderObject
node
in
dirtyNodes
..
sort
((
RenderObject
a
,
RenderObject
b
)
=>
b
.
depth
-
a
.
depth
))
{
assert
(
node
.
_layer
!=
null
);
assert
(
node
.
_layer
Handle
.
layer
!=
null
);
if
(
node
.
_needsPaint
&&
node
.
owner
==
this
)
{
if
(
node
.
_layer
!.
attached
)
{
if
(
node
.
_layer
Handle
.
layer
!.
attached
)
{
PaintingContext
.
repaintCompositedChild
(
node
);
}
else
{
node
.
_skippedPaintingOnLayer
();
...
...
@@ -1274,7 +1278,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
@mustCallSuper
void
dispose
()
{
assert
(!
_debugDisposed
);
_layer
=
null
;
_layer
Handle
.
layer
=
null
;
assert
(()
{
// TODO(dnfield): Enable this assert once clients have had a chance to
// migrate.
...
...
@@ -1478,7 +1482,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
_needsCompositingBitsUpdate
=
false
;
markNeedsCompositingBitsUpdate
();
}
if
(
_needsPaint
&&
_layer
!=
null
)
{
if
(
_needsPaint
&&
_layer
Handle
.
layer
!=
null
)
{
// Don't enter this block if we've never painted at all;
// scheduleInitialPaint() will handle it
_needsPaint
=
false
;
...
...
@@ -2050,14 +2054,22 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
/// never populating this field, or by setting it to null when the value of
/// [needsCompositing] changes from true to false.
///
/// If a new layer is created and stored in some other field on the render
/// object, the render object must use a [LayerHandle] to store it. A layer
/// handle will prevent the layer from being disposed before the render
/// object is finished with it, and it will also make sure that the layer
/// gets appropriately disposed when the render object creates a replacement
/// or nulls it out. The render object must null out the [LayerHandle.layer]
/// in its [dispose] method.
///
/// If this render object is a repaint boundary, the framework automatically
/// creates an [OffsetLayer] and populates this field prior to calling the
/// [paint] method. The [paint] method must not replace the value of this
/// field.
@protected
ContainerLayer
?
get
layer
{
assert
(!
isRepaintBoundary
||
(
_layer
==
null
||
_layer
is
OffsetLayer
)
);
return
_layer
;
assert
(!
isRepaintBoundary
||
_layerHandle
.
layer
==
null
||
_layerHandle
.
layer
is
OffsetLayer
);
return
_layer
Handle
.
layer
;
}
@protected
...
...
@@ -2068,9 +2080,10 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
'The framework creates and assigns an OffsetLayer to a repaint '
'boundary automatically.'
,
);
_layer
=
newLayer
;
_layer
Handle
.
layer
=
newLayer
;
}
ContainerLayer
?
_layer
;
final
LayerHandle
<
ContainerLayer
>
_layerHandle
=
LayerHandle
<
ContainerLayer
>();
/// In debug mode, the compositing layer that this render object uses to repaint.
///
...
...
@@ -2082,7 +2095,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
ContainerLayer
?
get
debugLayer
{
ContainerLayer
?
result
;
assert
(()
{
result
=
_layer
;
result
=
_layer
Handle
.
layer
;
return
true
;
}());
return
result
;
...
...
@@ -2218,7 +2231,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
}());
// If we always have our own layer, then we can just repaint
// ourselves without involving any other nodes.
assert
(
_layer
is
OffsetLayer
);
assert
(
_layer
Handle
.
layer
is
OffsetLayer
);
if
(
owner
!=
null
)
{
owner
!.
_nodesNeedingPaint
.
add
(
this
);
owner
!.
requestVisualUpdate
();
...
...
@@ -2251,14 +2264,14 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
assert
(
attached
);
assert
(
isRepaintBoundary
);
assert
(
_needsPaint
);
assert
(
_layer
!=
null
);
assert
(!
_layer
!.
attached
);
assert
(
_layer
Handle
.
layer
!=
null
);
assert
(!
_layer
Handle
.
layer
!.
attached
);
AbstractNode
?
node
=
parent
;
while
(
node
is
RenderObject
)
{
if
(
node
.
isRepaintBoundary
)
{
if
(
node
.
_layer
==
null
)
if
(
node
.
_layer
Handle
.
layer
==
null
)
break
;
// looks like the subtree here has never been painted. let it handle itself.
if
(
node
.
_layer
!.
attached
)
if
(
node
.
_layer
Handle
.
layer
!.
attached
)
break
;
// it's the one that detached us, so it's the one that will decide to repaint us.
node
.
_needsPaint
=
true
;
}
...
...
@@ -2278,8 +2291,8 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
assert
(
parent
is
!
RenderObject
);
assert
(!
owner
!.
_debugDoingPaint
);
assert
(
isRepaintBoundary
);
assert
(
_layer
==
null
);
_layer
=
rootLayer
;
assert
(
_layer
Handle
.
layer
==
null
);
_layer
Handle
.
layer
=
rootLayer
;
assert
(
_needsPaint
);
owner
!.
_nodesNeedingPaint
.
add
(
this
);
}
...
...
@@ -2296,9 +2309,9 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
assert
(
parent
is
!
RenderObject
);
assert
(!
owner
!.
_debugDoingPaint
);
assert
(
isRepaintBoundary
);
assert
(
_layer
!=
null
);
// use scheduleInitialPaint the first time
_layer
!.
detach
();
_layer
=
rootLayer
;
assert
(
_layer
Handle
.
layer
!=
null
);
// use scheduleInitialPaint the first time
_layer
Handle
.
layer
!.
detach
();
_layer
Handle
.
layer
=
rootLayer
;
markNeedsPaint
();
}
...
...
@@ -2388,7 +2401,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
_debugDoingThisPaint
=
true
;
debugLastActivePaint
=
_debugActivePaint
;
_debugActivePaint
=
this
;
assert
(!
isRepaintBoundary
||
_layer
!=
null
);
assert
(!
isRepaintBoundary
||
_layer
Handle
.
layer
!=
null
);
return
true
;
}());
_needsPaint
=
false
;
...
...
@@ -2983,7 +2996,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
properties
.
add
(
DiagnosticsProperty
<
ParentData
>(
'parentData'
,
parentData
,
tooltip:
_debugCanParentUseSize
==
true
?
'can use size'
:
null
,
missingIfNull:
true
));
properties
.
add
(
DiagnosticsProperty
<
Constraints
>(
'constraints'
,
_constraints
,
missingIfNull:
true
));
// don't access it via the "layer" getter since that's only valid when we don't need paint
properties
.
add
(
DiagnosticsProperty
<
ContainerLayer
>(
'layer'
,
_layer
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
ContainerLayer
>(
'layer'
,
_layer
Handle
.
layer
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
SemanticsNode
>(
'semantics node'
,
_semantics
,
defaultValue:
null
));
properties
.
add
(
FlagProperty
(
'isBlockingSemanticsOfPreviouslyPaintedNodes'
,
...
...
packages/flutter/lib/src/rendering/platform_view.dart
View file @
025397ae
...
...
@@ -209,21 +209,27 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
// Clip the texture if it's going to paint out of the bounds of the renter box
// (see comment in _paintTexture for an explanation of when this happens).
if
((
size
.
width
<
_currentAndroidViewSize
.
width
||
size
.
height
<
_currentAndroidViewSize
.
height
)
&&
clipBehavior
!=
Clip
.
none
)
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
true
,
offset
,
offset
&
size
,
_paintTexture
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
return
;
}
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
_paintTexture
(
context
,
offset
);
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
void
_paintTexture
(
PaintingContext
context
,
Offset
offset
)
{
// As resizing the Android view happens asynchronously we don't know exactly when is a
...
...
packages/flutter/lib/src/rendering/rotated_box.dart
View file @
025397ae
...
...
@@ -117,19 +117,25 @@ class RenderRotatedBox extends RenderBox with RenderObjectWithChildMixin<RenderB
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
{
_transformLayer
=
context
.
pushTransform
(
_transformLayer
.
layer
=
context
.
pushTransform
(
needsCompositing
,
offset
,
_paintTransform
!,
_paintChild
,
oldLayer:
_transformLayer
,
oldLayer:
_transformLayer
.
layer
,
);
}
else
{
_transformLayer
=
null
;
_transformLayer
.
layer
=
null
;
}
}
TransformLayer
?
_transformLayer
;
final
LayerHandle
<
TransformLayer
>
_transformLayer
=
LayerHandle
<
TransformLayer
>();
@override
void
dispose
()
{
_transformLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
void
applyPaintTransform
(
RenderBox
child
,
Matrix4
transform
)
{
...
...
packages/flutter/lib/src/rendering/shifted_box.dart
View file @
025397ae
...
...
@@ -801,17 +801,17 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
}
if
(
clipBehavior
==
Clip
.
none
)
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
super
.
paint
(
context
,
offset
);
}
else
{
// We have overflow and the clipBehavior isn't none. Clip it.
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
super
.
paint
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectL
ayer
,
oldLayer:
_clipRectLayer
.
l
ayer
,
);
}
...
...
@@ -822,7 +822,13 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
}());
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
Rect
?
describeApproximatePaintClip
(
RenderObject
child
)
{
...
...
packages/flutter/lib/src/rendering/stack.dart
View file @
025397ae
...
...
@@ -632,21 +632,27 @@ class RenderStack extends RenderBox
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
clipBehavior
!=
Clip
.
none
&&
_hasVisualOverflow
)
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
paintStack
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
else
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
paintStack
(
context
,
offset
);
}
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
Rect
?
describeApproximatePaintClip
(
RenderObject
child
)
=>
_hasVisualOverflow
?
Offset
.
zero
&
size
:
null
;
...
...
packages/flutter/lib/src/rendering/viewport.dart
View file @
025397ae
...
...
@@ -632,21 +632,27 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
if
(
firstChild
==
null
)
return
;
if
(
hasVisualOverflow
&&
clipBehavior
!=
Clip
.
none
)
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
_paintContents
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
else
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
_paintContents
(
context
,
offset
);
}
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
void
_paintContents
(
PaintingContext
context
,
Offset
offset
)
{
for
(
final
RenderSliver
child
in
childrenInPaintOrder
)
{
...
...
packages/flutter/lib/src/rendering/wrap.dart
View file @
025397ae
...
...
@@ -761,21 +761,27 @@ class RenderWrap extends RenderBox
// TODO(ianh): move the debug flex overflow paint logic somewhere common so
// it can be reused here
if
(
_hasVisualOverflow
&&
clipBehavior
!=
Clip
.
none
)
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
defaultPaint
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
else
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
defaultPaint
(
context
,
offset
);
}
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
...
...
packages/flutter/lib/src/widgets/overlay.dart
View file @
025397ae
...
...
@@ -787,21 +787,27 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
_hasVisualOverflow
&&
clipBehavior
!=
Clip
.
none
)
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
paintStack
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
else
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
paintStack
(
context
,
offset
);
}
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
void
visitChildrenForSemantics
(
RenderObjectVisitor
visitor
)
{
...
...
packages/flutter/lib/src/widgets/single_child_scroll_view.dart
View file @
025397ae
...
...
@@ -620,22 +620,28 @@ class _RenderSingleChildViewport extends RenderBox with RenderObjectWithChildMix
}
if
(
_shouldClipAtPaintOffset
(
paintOffset
)
&&
clipBehavior
!=
Clip
.
none
)
{
_clipRectLayer
=
context
.
pushClipRect
(
_clipRectLayer
.
layer
=
context
.
pushClipRect
(
needsCompositing
,
offset
,
Offset
.
zero
&
size
,
paintContents
,
clipBehavior:
clipBehavior
,
oldLayer:
_clipRectLayer
,
oldLayer:
_clipRectLayer
.
layer
,
);
}
else
{
_clipRectLayer
=
null
;
_clipRectLayer
.
layer
=
null
;
paintContents
(
context
,
offset
);
}
}
}
ClipRectLayer
?
_clipRectLayer
;
final
LayerHandle
<
ClipRectLayer
>
_clipRectLayer
=
LayerHandle
<
ClipRectLayer
>();
@override
void
dispose
()
{
_clipRectLayer
.
layer
=
null
;
super
.
dispose
();
}
@override
void
applyPaintTransform
(
RenderBox
child
,
Matrix4
transform
)
{
...
...
packages/flutter/test/foundation/service_extensions_test.dart
View file @
025397ae
...
...
@@ -262,6 +262,7 @@ void main() {
r' owner: RenderView#[0-9a-f]{5}\n'
r' creator: RenderView\n'
r' engine layer: (TransformEngineLayer|PersistedTransform)#[0-9a-f]{5}\n'
r' handles: 1\n'
r' offset: Offset\(0\.0, 0\.0\)\n'
r' transform:\n'
r' \[0] 3\.0,0\.0,0\.0,0\.0\n'
...
...
packages/flutter/test/rendering/box_test.dart
View file @
025397ae
...
...
@@ -648,7 +648,7 @@ void main() {
child:
box200x200
,
);
layout
(
defaultBox
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
defaultBox
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
defaultBox
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
none
));
for
(
final
Clip
clip
in
Clip
.
values
)
{
...
...
@@ -659,7 +659,7 @@ void main() {
clipBehavior:
clip
,
);
layout
(
box
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
box
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
box
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
}
});
...
...
packages/flutter/test/rendering/debug_test.dart
View file @
025397ae
...
...
@@ -163,9 +163,10 @@ void main() {
);
layout
(
root
);
dynamic
error
;
final
PaintingContext
context
=
PaintingContext
(
ContainerLayer
(),
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
800.0
,
600.0
));
try
{
s
.
debugPaint
(
PaintingContext
(
ContainerLayer
(),
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
800.0
,
600.0
))
,
context
,
const
Offset
(
0.0
,
500
),
);
}
catch
(
e
)
{
...
...
@@ -195,9 +196,10 @@ void main() {
);
layout
(
root
);
dynamic
error
;
final
PaintingContext
context
=
PaintingContext
(
ContainerLayer
(),
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
800.0
,
600.0
));
try
{
s
.
debugPaint
(
PaintingContext
(
ContainerLayer
(),
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
800.0
,
600.0
))
,
context
,
const
Offset
(
0.0
,
500
),
);
}
catch
(
e
)
{
...
...
packages/flutter/test/rendering/editable_test.dart
View file @
025397ae
...
...
@@ -47,7 +47,7 @@ void main() {
selection:
const
TextSelection
(
baseOffset:
0
,
extentOffset:
0
),
);
layout
(
defaultEditable
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
defaultEditable
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
defaultEditable
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
hardEdge
));
context
.
clipBehavior
=
Clip
.
none
;
// Reset as Clip.none won't write into clipBehavior.
...
...
@@ -63,7 +63,7 @@ void main() {
clipBehavior:
clip
,
);
layout
(
editable
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
editable
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
editable
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
}
});
...
...
packages/flutter/test/rendering/flex_test.dart
View file @
025397ae
...
...
@@ -62,13 +62,13 @@ void main() {
// By default, clipBehavior should be Clip.none
final
RenderFlex
defaultFlex
=
RenderFlex
(
direction:
Axis
.
vertical
,
children:
<
RenderBox
>[
box200x200
]);
layout
(
defaultFlex
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
defaultFlex
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
defaultFlex
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
none
));
for
(
final
Clip
clip
in
Clip
.
values
)
{
final
RenderFlex
flex
=
RenderFlex
(
direction:
Axis
.
vertical
,
children:
<
RenderBox
>[
box200x200
],
clipBehavior:
clip
);
layout
(
flex
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
flex
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
flex
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
}
});
...
...
packages/flutter/test/rendering/layers_test.dart
View file @
025397ae
...
...
@@ -256,7 +256,7 @@ void main() {
);
});
test
(
'PictureLayer prints picture,
engine layer, and
raster cache hints in debug info'
,
()
{
test
(
'PictureLayer prints picture, raster cache hints in debug info'
,
()
{
final
PictureRecorder
recorder
=
PictureRecorder
();
final
Canvas
canvas
=
Canvas
(
recorder
);
canvas
.
drawPaint
(
Paint
());
...
...
@@ -267,10 +267,20 @@ void main() {
layer
.
willChangeHint
=
false
;
final
List
<
String
>
info
=
_getDebugInfo
(
layer
);
expect
(
info
,
contains
(
'picture:
${describeIdentity(picture)}
'
));
expect
(
info
,
contains
(
'engine layer:
${describeIdentity(null)}
'
));
expect
(
info
,
isNot
(
contains
(
'engine layer:
${describeIdentity(null)}
'
)
));
expect
(
info
,
contains
(
'raster cache hints: isComplex = true, willChange = false'
));
});
test
(
'Layer prints engineLayer if it is not null in debug info'
,
()
{
final
ConcreteLayer
layer
=
ConcreteLayer
();
List
<
String
>
info
=
_getDebugInfo
(
layer
);
expect
(
info
,
isNot
(
contains
(
'engine layer:
${describeIdentity(null)}
'
)));
layer
.
engineLayer
=
FakeEngineLayer
();
info
=
_getDebugInfo
(
layer
);
expect
(
info
,
contains
(
'engine layer:
${describeIdentity(layer.engineLayer)}
'
));
});
test
(
'mutating PictureLayer fields triggers needsAddToScene'
,
()
{
final
PictureLayer
pictureLayer
=
PictureLayer
(
Rect
.
zero
);
checkNeedsAddToScene
(
pictureLayer
,
()
{
...
...
@@ -591,6 +601,135 @@ void main() {
// layer.
parent
.
buildScene
(
SceneBuilder
());
},
skip:
isBrowser
);
// TODO(yjbanov): `toImage` doesn't work on the Web: https://github.com/flutter/flutter/issues/42767
// TODO(dnfield): remove this when https://github.com/flutter/flutter/issues/85066 is resolved.
const
bool
bug85066
=
true
;
test
(
'PictureLayer does not let you call dispose unless refcount is 0'
,
()
{
PictureLayer
layer
=
PictureLayer
(
Rect
.
zero
);
expect
(
layer
.
debugHandleCount
,
0
);
layer
.
dispose
();
expect
(
layer
.
debugDisposed
,
true
,
skip:
bug85066
);
layer
=
PictureLayer
(
Rect
.
zero
);
final
LayerHandle
<
PictureLayer
>
handle
=
LayerHandle
<
PictureLayer
>(
layer
);
expect
(
layer
.
debugHandleCount
,
1
);
expect
(()
=>
layer
.
dispose
(),
throwsAssertionError
);
handle
.
layer
=
null
;
expect
(
layer
.
debugHandleCount
,
0
);
expect
(
layer
.
debugDisposed
,
true
,
skip:
bug85066
);
expect
(()
=>
layer
.
dispose
(),
throwsAssertionError
,
skip:
bug85066
);
// already disposed.
});
test
(
'Layer append/remove increases/decreases handle count'
,
()
{
final
PictureLayer
layer
=
PictureLayer
(
Rect
.
zero
);
final
ContainerLayer
parent
=
ContainerLayer
();
expect
(
layer
.
debugHandleCount
,
0
);
expect
(
layer
.
debugDisposed
,
false
);
parent
.
append
(
layer
);
expect
(
layer
.
debugHandleCount
,
1
);
expect
(
layer
.
debugDisposed
,
false
);
layer
.
remove
();
expect
(
layer
.
debugHandleCount
,
0
);
expect
(
layer
.
debugDisposed
,
true
,
skip:
bug85066
);
});
test
(
'Layer.dispose disposes the engineLayer'
,
()
{
final
Layer
layer
=
ConcreteLayer
();
final
FakeEngineLayer
engineLayer
=
FakeEngineLayer
();
layer
.
engineLayer
=
engineLayer
;
expect
(
engineLayer
.
disposed
,
false
);
layer
.
dispose
();
expect
(
engineLayer
.
disposed
,
true
);
expect
(
layer
.
engineLayer
,
null
);
});
test
(
'Layer.engineLayer (set) disposes the engineLayer'
,
()
{
final
Layer
layer
=
ConcreteLayer
();
final
FakeEngineLayer
engineLayer
=
FakeEngineLayer
();
layer
.
engineLayer
=
engineLayer
;
expect
(
engineLayer
.
disposed
,
false
);
layer
.
engineLayer
=
null
;
expect
(
engineLayer
.
disposed
,
true
);
});
test
(
'PictureLayer.picture (set) disposes the picture'
,
()
{
final
PictureLayer
layer
=
PictureLayer
(
Rect
.
zero
);
final
FakePicture
picture
=
FakePicture
();
layer
.
picture
=
picture
;
expect
(
picture
.
disposed
,
false
);
layer
.
picture
=
null
;
expect
(
picture
.
disposed
,
true
);
});
test
(
'PictureLayer disposes the picture'
,
()
{
final
PictureLayer
layer
=
PictureLayer
(
Rect
.
zero
);
final
FakePicture
picture
=
FakePicture
();
layer
.
picture
=
picture
;
expect
(
picture
.
disposed
,
false
);
layer
.
dispose
();
expect
(
picture
.
disposed
,
true
);
});
test
(
'LayerHandle disposes the layer'
,
()
{
final
ConcreteLayer
layer
=
ConcreteLayer
();
final
ConcreteLayer
layer2
=
ConcreteLayer
();
expect
(
layer
.
debugHandleCount
,
0
);
expect
(
layer2
.
debugHandleCount
,
0
);
final
LayerHandle
<
ConcreteLayer
>
holder
=
LayerHandle
<
ConcreteLayer
>(
layer
);
expect
(
layer
.
debugHandleCount
,
1
);
expect
(
layer
.
debugDisposed
,
false
);
expect
(
layer2
.
debugHandleCount
,
0
);
expect
(
layer2
.
debugDisposed
,
false
);
holder
.
layer
=
layer
;
expect
(
layer
.
debugHandleCount
,
1
);
expect
(
layer
.
debugDisposed
,
false
);
expect
(
layer2
.
debugHandleCount
,
0
);
expect
(
layer2
.
debugDisposed
,
false
);
holder
.
layer
=
layer2
;
expect
(
layer
.
debugHandleCount
,
0
);
expect
(
layer
.
debugDisposed
,
true
,
skip:
bug85066
);
expect
(
layer2
.
debugHandleCount
,
1
);
expect
(
layer2
.
debugDisposed
,
false
);
holder
.
layer
=
null
;
expect
(
layer
.
debugHandleCount
,
0
);
expect
(
layer
.
debugDisposed
,
true
,
skip:
bug85066
);
expect
(
layer2
.
debugHandleCount
,
0
);
expect
(
layer2
.
debugDisposed
,
true
,
skip:
bug85066
);
expect
(()
=>
holder
.
layer
=
layer
,
throwsAssertionError
,
skip:
bug85066
);
});
}
class
FakeEngineLayer
extends
Fake
implements
EngineLayer
{
bool
disposed
=
false
;
@override
void
dispose
()
{
assert
(!
disposed
);
disposed
=
true
;
}
}
class
FakePicture
extends
Fake
implements
Picture
{
bool
disposed
=
false
;
@override
void
dispose
()
{
assert
(!
disposed
);
disposed
=
true
;
}
}
class
ConcreteLayer
extends
Layer
{
@override
void
addToScene
(
SceneBuilder
builder
,
[
Offset
layerOffset
=
Offset
.
zero
])
{}
}
class
_TestAlwaysNeedsAddToSceneLayer
extends
ContainerLayer
{
...
...
packages/flutter/test/rendering/object_paint_dispose_test.dart
0 → 100644
View file @
025397ae
// 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/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
// TODO(dnfield): remove when https://github.com/flutter/flutter/issues/85066 is resolved.
const
bool
bug85066
=
true
;
testWidgets
(
'Tracks picture layers accurately when painting is interleaved with a pushLayer'
,
(
WidgetTester
tester
)
async
{
// Creates a RenderObject that will paint into multiple picture layers.
// Asserts that both layers get a handle, and that all layers get correctly
// released.
final
GlobalKey
key
=
GlobalKey
();
await
tester
.
pumpWidget
(
RepaintBoundary
(
child:
CustomPaint
(
key:
key
,
painter:
SimplePainter
(),
child:
const
RepaintBoundary
(
child:
Placeholder
()),
foregroundPainter:
SimplePainter
(),
),
));
final
List
<
Layer
>
layers
=
tester
.
binding
.
renderView
.
debugLayer
!.
depthFirstIterateChildren
();
final
RenderObject
renderObject
=
key
.
currentContext
!.
findRenderObject
()!;
for
(
final
Layer
layer
in
layers
)
{
expect
(
layer
.
debugDisposed
,
false
);
}
await
tester
.
pumpWidget
(
const
SizedBox
());
for
(
final
Layer
layer
in
layers
)
{
expect
(
layer
.
debugDisposed
,
true
,
skip:
bug85066
);
}
expect
(
renderObject
.
debugDisposed
,
true
);
});
}
class
SimplePainter
extends
CustomPainter
{
@override
void
paint
(
Canvas
canvas
,
Size
size
)
{
canvas
.
drawPaint
(
Paint
());
}
@override
bool
shouldRepaint
(
SimplePainter
oldDelegate
)
=>
true
;
}
packages/flutter/test/rendering/rendering_tester.dart
View file @
025397ae
...
...
@@ -305,7 +305,6 @@ class TestClipPaintingContext extends PaintingContext {
ClipRectLayer
?
oldLayer
,
})
{
this
.
clipBehavior
=
clipBehavior
;
return
null
;
}
Clip
clipBehavior
=
Clip
.
none
;
...
...
packages/flutter/test/rendering/stack_test.dart
View file @
025397ae
...
...
@@ -83,7 +83,7 @@ void main() {
parentData
.
left
=
parentData
.
right
=
0
;
}
layout
(
stack
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
stack
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
stack
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
}
});
...
...
packages/flutter/test/rendering/wrap_test.dart
View file @
025397ae
...
...
@@ -209,13 +209,13 @@ void main() {
// By default, clipBehavior should be Clip.none
final
RenderWrap
defaultWrap
=
RenderWrap
(
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
box200x200
]);
layout
(
defaultWrap
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
defaultWrap
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
defaultWrap
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
Clip
.
none
));
for
(
final
Clip
clip
in
Clip
.
values
)
{
final
RenderWrap
wrap
=
RenderWrap
(
textDirection:
TextDirection
.
ltr
,
children:
<
RenderBox
>[
box200x200
],
clipBehavior:
clip
);
layout
(
wrap
,
constraints:
viewport
,
phase:
EnginePhase
.
composite
,
onErrors:
expectOverflowedErrors
);
wrap
.
paint
(
context
,
Offset
.
zero
);
context
.
paintChild
(
wrap
,
Offset
.
zero
);
expect
(
context
.
clipBehavior
,
equals
(
clip
));
}
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment