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
e48efdca
Commit
e48efdca
authored
Dec 21, 2015
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #982 from Hixie/fewer-bit-updates
Less tree walking for compositing bits updates.
parents
884c8e9e
ab01c7bf
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
71 additions
and
30 deletions
+71
-30
binding.dart
packages/flutter/lib/src/rendering/binding.dart
+1
-1
object.dart
packages/flutter/lib/src/rendering/object.dart
+60
-25
rendering_tester.dart
packages/flutter/test/rendering/rendering_tester.dart
+4
-1
stack_test.dart
packages/flutter/test/rendering/stack_test.dart
+6
-3
No files found.
packages/flutter/lib/src/rendering/binding.dart
View file @
e48efdca
...
...
@@ -69,7 +69,7 @@ abstract class Renderer extends Scheduler
void
beginFrame
()
{
assert
(
renderView
!=
null
);
RenderObject
.
flushLayout
();
renderView
.
update
CompositingBits
();
RenderObject
.
flush
CompositingBits
();
RenderObject
.
flushPaint
();
renderView
.
compositeFrame
();
}
...
...
packages/flutter/lib/src/rendering/object.dart
View file @
e48efdca
...
...
@@ -391,6 +391,10 @@ RenderingExceptionHandler debugRenderingExceptionHandler;
/// for their children.
abstract
class
RenderObject
extends
AbstractNode
implements
HitTestTarget
{
RenderObject
()
{
_needsCompositing
=
hasLayer
;
}
// LAYOUT
/// Data for use by the parent render object.
...
...
@@ -492,7 +496,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
}
}
static
List
<
RenderObject
>
_nodesNeedingLayout
=
new
List
<
RenderObject
>()
;
static
List
<
RenderObject
>
_nodesNeedingLayout
=
<
RenderObject
>[]
;
bool
_needsLayout
=
true
;
/// Whether this render object's layout information is dirty.
bool
get
needsLayout
=>
_needsLayout
;
...
...
@@ -597,11 +601,11 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
// TODO(ianh): assert that we're not allowing previously dirty nodes to redirty themeselves
while
(
_nodesNeedingLayout
.
isNotEmpty
)
{
List
<
RenderObject
>
dirtyNodes
=
_nodesNeedingLayout
;
_nodesNeedingLayout
=
new
List
<
RenderObject
>()
;
dirtyNodes
..
sort
((
RenderObject
a
,
RenderObject
b
)
=>
a
.
depth
-
b
.
depth
)..
forEach
((
RenderObject
node
)
{
_nodesNeedingLayout
=
<
RenderObject
>[]
;
for
(
RenderObject
node
in
dirtyNodes
..
sort
((
RenderObject
a
,
RenderObject
b
)
=>
a
.
depth
-
b
.
depth
)
)
{
if
(
node
.
_needsLayout
&&
node
.
attached
)
node
.
_layoutWithoutResize
();
}
);
}
}
}
finally
{
_debugDoingLayout
=
false
;
...
...
@@ -822,7 +826,8 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
static
RenderObject
_debugActivePaint
=
null
;
static
RenderObject
get
debugActivePaint
=>
_debugActivePaint
;
static
List
<
RenderObject
>
_nodesNeedingPaint
=
new
List
<
RenderObject
>();
static
List
<
RenderObject
>
_nodesNeedingPaint
=
<
RenderObject
>[];
static
List
<
RenderObject
>
_nodesNeedingCompositingBitsUpdate
=
<
RenderObject
>[];
/// Whether this render object paints using a composited layer.
///
...
...
@@ -843,49 +848,79 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
return
_layer
;
}
bool
_needsCompositingBitsUpdate
=
true
;
bool
_needsCompositingBitsUpdate
=
false
;
// set to true when a child is added
/// Mark the compositing state for this render object as dirty.
///
/// When the subtree is mutated, we need to recompute our [needsCompositing]
/// bit, and our ancestors need to do the same (in case ours changed).
/// Therefore, [adoptChild] and [dropChild] call
/// [markNeedsCompositingBitsUpdate].
/// When the subtree is mutated, we need to recompute our
/// [needsCompositing] bit, and some of our ancestors need to do the
/// same (in case ours changed in a way that will change theirs). To
/// this end, [adoptChild] and [dropChild] call this method, and, as
/// necessary, this method calls the parent's, etc, walking up the
/// tree to mark all the nodes that need updating.
///
/// This method does not schedule a rendering frame, because since
/// it cannot be the case that _only_ the compositing bits changed,
/// something else will have scheduled a frame for us.
void
_markNeedsCompositingBitsUpdate
()
{
if
(
_needsCompositingBitsUpdate
)
return
;
_needsCompositingBitsUpdate
=
true
;
if
(
parent
is
RenderObject
)
{
final
RenderObject
parent
=
this
.
parent
;
if
(
parent
.
_needsCompositingBitsUpdate
)
return
;
if
(!
hasLayer
&&
!
parent
.
hasLayer
)
{
parent
.
_markNeedsCompositingBitsUpdate
();
return
;
}
}
assert
(()
{
final
AbstractNode
parent
=
this
.
parent
;
if
(
parent
is
RenderObject
)
parent
.
_markNeedsCompositingBitsUpdate
();
assert
(
parent
==
this
.
parent
);
return
parent
.
_needsCompositing
;
return
true
;
});
// parent is fine (or there isn't one), but we are dirty
_nodesNeedingCompositingBitsUpdate
.
add
(
this
);
}
/// Updates the [needsCompositing] bits.
///
/// Called as part of the rendering pipeline after [flushLayout] and before
/// [flushPaint].
static
void
flushCompositingBits
()
{
Timeline
.
startSync
(
'Compositing Bits'
);
_nodesNeedingCompositingBitsUpdate
.
sort
((
RenderObject
a
,
RenderObject
b
)
=>
a
.
depth
-
b
.
depth
);
for
(
RenderObject
node
in
_nodesNeedingCompositingBitsUpdate
)
{
if
(
node
.
attached
)
node
.
_updateCompositingBits
();
}
_nodesNeedingCompositingBitsUpdate
.
clear
();
Timeline
.
finishSync
();
}
bool
_needsCompositing
=
false
;
bool
_needsCompositing
;
// initialised in the constructor
/// Whether we or one of our descendants has a compositing layer.
///
/// Only legal to call after [flushLayout] and [
update
CompositingBits] have
/// Only legal to call after [flushLayout] and [
flush
CompositingBits] have
/// been called.
bool
get
needsCompositing
{
assert
(!
_needsCompositingBitsUpdate
);
// make sure we don't use this bit when it is dirty
return
_needsCompositing
;
}
/// Updates the [needsCompositing] bits.
///
/// Called as part of the rendering pipeline after [flushLayout] and before
/// [flushPaint].
void
updateCompositingBits
()
{
void
_updateCompositingBits
()
{
if
(!
_needsCompositingBitsUpdate
)
return
;
bool
didHaveCompositedDescendant
=
_needsCompositing
;
bool
oldNeedsCompositing
=
_needsCompositing
;
visitChildren
((
RenderObject
child
)
{
child
.
updateCompositingBits
();
child
.
_
updateCompositingBits
();
if
(
child
.
needsCompositing
)
_needsCompositing
=
true
;
});
if
(
hasLayer
)
_needsCompositing
=
true
;
if
(
didHaveCompositedDescendant
!=
_needsCompositing
)
if
(
oldNeedsCompositing
!=
_needsCompositing
)
markNeedsPaint
();
_needsCompositingBitsUpdate
=
false
;
}
...
...
@@ -946,7 +981,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
_debugDoingPaint
=
true
;
try
{
List
<
RenderObject
>
dirtyNodes
=
_nodesNeedingPaint
;
_nodesNeedingPaint
=
new
List
<
RenderObject
>()
;
_nodesNeedingPaint
=
<
RenderObject
>[]
;
// Sort the dirty nodes in reverse order (deepest first).
for
(
RenderObject
node
in
dirtyNodes
..
sort
((
RenderObject
a
,
RenderObject
b
)
=>
b
.
depth
-
a
.
depth
))
{
assert
(
node
.
_needsPaint
);
...
...
packages/flutter/test/rendering/rendering_tester.dart
View file @
e48efdca
...
...
@@ -21,6 +21,7 @@ class TestRenderView extends RenderView {
enum
EnginePhase
{
layout
,
compositingBits
,
paint
,
composite
}
...
...
@@ -39,7 +40,9 @@ class TestRenderingFlutterBinding extends BindingBase with Scheduler, Renderer,
RenderObject
.
flushLayout
();
if
(
phase
==
EnginePhase
.
layout
)
return
;
renderer
.
renderView
.
updateCompositingBits
();
RenderObject
.
flushCompositingBits
();
if
(
phase
==
EnginePhase
.
compositingBits
)
return
;
RenderObject
.
flushPaint
();
if
(
phase
==
EnginePhase
.
paint
)
return
;
...
...
packages/flutter/test/rendering/stack_test.dart
View file @
e48efdca
...
...
@@ -10,18 +10,21 @@ import 'rendering_tester.dart';
void
main
(
)
{
test
(
'Stack can layout with top, right, bottom, left 0.0'
,
()
{
RenderBox
size
=
new
RenderConstrainedBox
(
additionalConstraints:
new
BoxConstraints
.
tight
(
const
Size
(
100.0
,
100.0
)));
additionalConstraints:
new
BoxConstraints
.
tight
(
const
Size
(
100.0
,
100.0
))
);
RenderBox
red
=
new
RenderDecoratedBox
(
decoration:
new
BoxDecoration
(
backgroundColor:
const
Color
(
0xFFFF0000
)
),
child:
size
);
child:
size
);
RenderBox
green
=
new
RenderDecoratedBox
(
decoration:
new
BoxDecoration
(
backgroundColor:
const
Color
(
0xFFFF0000
)
));
)
);
RenderBox
stack
=
new
RenderStack
(
children:
<
RenderBox
>[
red
,
green
]);
(
green
.
parentData
as
StackParentData
)
...
...
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