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
bb5a82a7
Commit
bb5a82a7
authored
Mar 18, 2016
by
Kris Giesing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow independent rendering pipelines
Fixes #2723
parent
e074af80
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
274 additions
and
168 deletions
+274
-168
layout_bench.dart
packages/flutter/benchmark/stocks/layout_bench.dart
+1
-1
README.md
packages/flutter/lib/src/rendering/README.md
+2
-2
binding.dart
packages/flutter/lib/src/rendering/binding.dart
+9
-5
block.dart
packages/flutter/lib/src/rendering/block.dart
+2
-2
box.dart
packages/flutter/lib/src/rendering/box.dart
+3
-8
child_view.dart
packages/flutter/lib/src/rendering/child_view.dart
+2
-2
node.dart
packages/flutter/lib/src/rendering/node.dart
+14
-8
object.dart
packages/flutter/lib/src/rendering/object.dart
+129
-118
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+2
-2
semantics.dart
packages/flutter/lib/src/rendering/semantics.dart
+7
-6
view.dart
packages/flutter/lib/src/rendering/view.dart
+1
-1
viewport.dart
packages/flutter/lib/src/rendering/viewport.dart
+2
-2
gesture_detector.dart
packages/flutter/lib/src/widgets/gesture_detector.dart
+5
-1
independent_layout_test.dart
packages/flutter/test/rendering/independent_layout_test.dart
+84
-0
rendering_tester.dart
packages/flutter/test/rendering/rendering_tester.dart
+4
-4
sprite_box.dart
packages/flutter_sprites/lib/src/sprite_box.dart
+2
-2
widget_tester.dart
packages/flutter_test/lib/src/widget_tester.dart
+4
-4
analyze.dart
packages/flutter_tools/lib/src/commands/analyze.dart
+1
-0
No files found.
packages/flutter/benchmark/stocks/layout_bench.dart
View file @
bb5a82a7
...
...
@@ -31,7 +31,7 @@ void main() {
for
(
int
i
=
0
;
i
<
_kNumberOfIterations
||
_kRunForever
;
++
i
)
{
renderView
.
configuration
=
(
i
%
2
==
0
)
?
big
:
small
;
RenderObject
.
flushLayout
();
WidgetFlutterBinding
.
instance
.
pipelineOwner
.
flushLayout
();
}
watch
.
stop
();
...
...
packages/flutter/lib/src/rendering/README.md
View file @
bb5a82a7
...
...
@@ -20,8 +20,8 @@ The last phase of a frame is the Semantics phase. This only occurs if
a semantics server has been installed, for example if the user is
using an accessibility tool.
Each frame, the semantics phase starts with a call to the
static
`
RenderObject
.flushSemantics()`
method from the
`Renderer`
binding's
Each frame, the semantics phase starts with a call to the
`
PipelineOwner
.flushSemantics()`
method from the
`Renderer`
binding's
`beginFrame()`
method.
Each node marked as needing semantics (which initially is just the
...
...
packages/flutter/lib/src/rendering/binding.dart
View file @
bb5a82a7
...
...
@@ -48,6 +48,10 @@ abstract class Renderer extends Object with Scheduler, Services
handleMetricsChanged
();
// configures renderView's metrics
}
/// The render tree's owner, which maintains dirty state for layout,
/// composite, paint, and accessibility semantics
final
PipelineOwner
pipelineOwner
=
new
PipelineOwner
();
/// The render tree that's attached to the output surface.
RenderView
get
renderView
=>
_renderView
;
RenderView
_renderView
;
...
...
@@ -58,7 +62,7 @@ abstract class Renderer extends Object with Scheduler, Services
if
(
_renderView
!=
null
)
_renderView
.
detach
();
_renderView
=
value
;
_renderView
.
attach
();
_renderView
.
attach
(
pipelineOwner
);
}
void
handleMetricsChanged
()
{
...
...
@@ -81,12 +85,12 @@ abstract class Renderer extends Object with Scheduler, Services
/// Pump the rendering pipeline to generate a frame.
void
beginFrame
()
{
assert
(
renderView
!=
null
);
RenderObject
.
flushLayout
();
RenderObject
.
flushCompositingBits
();
RenderObject
.
flushPaint
();
pipelineOwner
.
flushLayout
();
pipelineOwner
.
flushCompositingBits
();
pipelineOwner
.
flushPaint
();
renderView
.
compositeFrame
();
// this sends the bits to the GPU
if
(
SemanticsNode
.
hasListeners
)
{
RenderObject
.
flushSemantics
();
pipelineOwner
.
flushSemantics
();
SemanticsNode
.
sendSemanticsTree
();
}
}
...
...
packages/flutter/lib/src/rendering/block.dart
View file @
bb5a82a7
...
...
@@ -337,8 +337,8 @@ class RenderBlockViewport extends RenderBlockBase {
}
@override
void
attach
()
{
super
.
attach
();
void
attach
(
PipelineOwner
owner
)
{
super
.
attach
(
owner
);
_overlayPainter
?.
attach
(
this
);
}
...
...
packages/flutter/lib/src/rendering/box.dart
View file @
bb5a82a7
...
...
@@ -388,12 +388,7 @@ class BoxHitTestEntry extends HitTestEntry {
/// Parent data used by [RenderBox] and its subclasses.
class
BoxParentData
extends
ParentData
{
/// The offset at which to paint the child in the parent's coordinate system
Offset
get
offset
=>
_offset
;
Offset
_offset
=
Offset
.
zero
;
void
set
offset
(
Offset
value
)
{
assert
(
RenderObject
.
debugDoingLayout
);
_offset
=
value
;
}
Offset
offset
=
Offset
.
zero
;
@override
String
toString
()
=>
'offset=
$offset
'
;
...
...
@@ -556,9 +551,9 @@ abstract class RenderBox extends RenderObject {
assert
(!
_debugDoingBaseline
);
assert
(()
{
final
RenderObject
parent
=
this
.
parent
;
if
(
RenderObject
.
debugDoingLayout
)
if
(
owner
.
debugDoingLayout
)
return
(
RenderObject
.
debugActiveLayout
==
parent
)
&&
parent
.
debugDoingThisLayout
;
if
(
RenderObject
.
debugDoingPaint
)
if
(
owner
.
debugDoingPaint
)
return
((
RenderObject
.
debugActivePaint
==
parent
)
&&
parent
.
debugDoingThisPaint
)
||
((
RenderObject
.
debugActivePaint
==
this
)
&&
debugDoingThisPaint
);
assert
(
parent
==
this
.
parent
);
...
...
packages/flutter/lib/src/rendering/child_view.dart
View file @
bb5a82a7
...
...
@@ -171,8 +171,8 @@ class RenderChildView extends RenderBox {
}
@override
void
attach
()
{
super
.
attach
();
void
attach
(
PipelineOwner
owner
)
{
super
.
attach
(
owner
);
_child
?.
_attach
();
}
...
...
packages/flutter/lib/src/rendering/node.dart
View file @
bb5a82a7
...
...
@@ -51,7 +51,7 @@ class AbstractNode {
/// Call only from overrides of [redepthChildren]
void
redepthChild
(
AbstractNode
child
)
{
assert
(
child
.
_attached
==
_attached
);
assert
(
child
.
owner
==
owner
);
if
(
child
.
_depth
<=
_depth
)
{
child
.
_depth
=
_depth
+
1
;
child
.
redepthChildren
();
...
...
@@ -62,16 +62,21 @@ class AbstractNode {
/// redepthChild(child) for each child. Do not call directly.
void
redepthChildren
()
{
}
bool
_attached
=
false
;
Object
_owner
;
/// The owner for this node (null if unattached).
Object
get
owner
=>
_owner
;
/// Whether this node is in a tree whose root is attached to something.
bool
get
attached
=>
_
attached
;
bool
get
attached
=>
_
owner
!=
null
;
/// Mark this node as attached.
/// Mark this node as attached
to the given owner
.
///
/// Typically called only from the parent's attach(), and to mark the root of
/// a tree attached.
void
attach
()
{
_attached
=
true
;
void
attach
(
Object
owner
)
{
assert
(
owner
!=
null
);
assert
(
_owner
==
null
);
_owner
=
owner
;
}
/// Mark this node as detached.
...
...
@@ -79,7 +84,8 @@ class AbstractNode {
/// Typically called only from the parent's detach(), and to mark the root of
/// a tree detached.
void
detach
()
{
_attached
=
false
;
assert
(
_owner
!=
null
);
_owner
=
null
;
}
AbstractNode
_parent
;
...
...
@@ -99,7 +105,7 @@ class AbstractNode {
});
child
.
_parent
=
this
;
if
(
attached
)
child
.
attach
();
child
.
attach
(
_owner
);
redepthChild
(
child
);
}
...
...
packages/flutter/lib/src/rendering/object.dart
View file @
bb5a82a7
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
bb5a82a7
...
...
@@ -1035,8 +1035,8 @@ class RenderDecoratedBox extends RenderProxyBox {
}
@override
void
attach
()
{
super
.
attach
();
void
attach
(
PipelineOwner
owner
)
{
super
.
attach
(
owner
);
_addListenerIfNeeded
();
}
...
...
packages/flutter/lib/src/rendering/semantics.dart
View file @
bb5a82a7
...
...
@@ -58,10 +58,11 @@ class SemanticsNode extends AbstractNode {
_actionHandler
=
handler
;
SemanticsNode
.
root
({
SemanticActionHandler
handler
SemanticActionHandler
handler
,
Object
owner
})
:
_id
=
0
,
_actionHandler
=
handler
{
attach
();
attach
(
owner
);
}
static
int
_lastIdentifier
=
0
;
...
...
@@ -265,8 +266,8 @@ class SemanticsNode extends AbstractNode {
static
Set
<
SemanticsNode
>
_detachedNodes
=
new
Set
<
SemanticsNode
>();
@override
void
attach
()
{
super
.
attach
();
void
attach
(
Object
owner
)
{
super
.
attach
(
owner
);
assert
(!
_nodes
.
containsKey
(
_id
));
_nodes
[
_id
]
=
this
;
_detachedNodes
.
remove
(
this
);
...
...
@@ -274,7 +275,7 @@ class SemanticsNode extends AbstractNode {
_inheritedMergeAllDescendantsIntoThisNode
=
parent
.
_shouldMergeAllDescendantsIntoThisNode
;
if
(
_children
!=
null
)
{
for
(
SemanticsNode
child
in
_children
)
child
.
attach
();
child
.
attach
(
owner
);
}
}
...
...
@@ -404,7 +405,7 @@ class SemanticsNode extends AbstractNode {
child
.
_inheritedMergeAllDescendantsIntoThisNode
=
false
;
// this can add the node to the dirty list
}
}
}
}
assert
(
_dirtyNodes
[
index
]
==
node
);
// make sure nothing went in front of us in the list
}
_dirtyNodes
.
sort
((
SemanticsNode
a
,
SemanticsNode
b
)
=>
a
.
depth
-
b
.
depth
);
...
...
packages/flutter/lib/src/rendering/view.dart
View file @
bb5a82a7
...
...
@@ -33,7 +33,7 @@ class ViewConfiguration {
/// The root of the render tree.
///
/// The view represents the total output surface of the render tree and handles
/// bootstraping the rendering pipeline. The view has a unique child
/// bootstrap
p
ing the rendering pipeline. The view has a unique child
/// [RenderBox], which is required to fill the entire output surface.
class
RenderView
extends
RenderObject
with
RenderObjectWithChildMixin
<
RenderBox
>
{
RenderView
({
...
...
packages/flutter/lib/src/rendering/viewport.dart
View file @
bb5a82a7
...
...
@@ -168,8 +168,8 @@ class RenderViewportBase extends RenderBox implements HasMainAxis {
}
@override
void
attach
()
{
super
.
attach
();
void
attach
(
PipelineOwner
owner
)
{
super
.
attach
(
owner
);
_overlayPainter
?.
attach
(
this
);
}
...
...
packages/flutter/lib/src/widgets/gesture_detector.dart
View file @
bb5a82a7
...
...
@@ -335,7 +335,11 @@ class RawGestureDetectorState extends State<RawGestureDetector> {
/// the gesture detector should be enabled.
void
replaceGestureRecognizers
(
Map
<
Type
,
GestureRecognizerFactory
>
gestures
)
{
assert
(()
{
if
(!
RenderObject
.
debugDoingLayout
)
{
// TODO kgiesing This assert will trigger if the owner of the current
// tree is different from the owner assigned to the renderer instance.
// Once elements have a notion of owners this assertion can be written
// more clearly.
if
(!
Renderer
.
instance
.
pipelineOwner
.
debugDoingLayout
)
{
throw
new
FlutterError
(
'Unexpected call to replaceGestureRecognizers() method of RawGestureDetectorState.
\n
'
'The replaceGestureRecognizers() method can only be called during the layout phase. '
...
...
packages/flutter/test/rendering/independent_layout_test.dart
0 → 100644
View file @
bb5a82a7
// Copyright 2016 The Chromium 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/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:test/test.dart'
;
import
'rendering_tester.dart'
;
class
TestLayout
{
TestLayout
()
{
// viewport incoming constraints are tight 800x600
// viewport is vertical by default
root
=
new
RenderViewport
(
child:
new
RenderCustomPaint
(
painter:
new
TestCallbackPainter
(
onPaint:
()
{
painted
=
true
;
}
),
child:
child
=
new
RenderConstrainedBox
(
additionalConstraints:
new
BoxConstraints
.
tightFor
(
height:
10.0
,
width:
10.0
)
)
)
);
}
RenderBox
root
;
RenderBox
child
;
bool
painted
=
false
;
}
void
main
(
)
{
test
(
'onscreen layout does not affect offscreen'
,
()
{
TestLayout
onscreen
=
new
TestLayout
();
TestLayout
offscreen
=
new
TestLayout
();
expect
(
onscreen
.
child
.
hasSize
,
isFalse
);
expect
(
onscreen
.
painted
,
isFalse
);
expect
(
offscreen
.
child
.
hasSize
,
isFalse
);
expect
(
offscreen
.
painted
,
isFalse
);
// Attach the offscreen to a custom render view and owner
RenderView
renderView
=
new
TestRenderView
();
PipelineOwner
pipelineOwner
=
new
PipelineOwner
();
renderView
.
attach
(
pipelineOwner
);
renderView
.
child
=
offscreen
.
root
;
renderView
.
scheduleInitialFrame
();
// Lay out the onscreen in the default binding
layout
(
onscreen
.
root
,
phase:
EnginePhase
.
layout
);
expect
(
onscreen
.
child
.
hasSize
,
isTrue
);
expect
(
onscreen
.
painted
,
isFalse
);
expect
(
onscreen
.
child
.
size
,
equals
(
const
Size
(
800.0
,
10.0
)));
// Make sure the offscreen didn't get laid out
expect
(
offscreen
.
child
.
hasSize
,
isFalse
);
expect
(
offscreen
.
painted
,
isFalse
);
// Now lay out the offscreen
pipelineOwner
.
flushLayout
();
expect
(
offscreen
.
child
.
hasSize
,
isTrue
);
expect
(
offscreen
.
painted
,
isFalse
);
});
test
(
'offscreen layout does not affect onscreen'
,
()
{
TestLayout
onscreen
=
new
TestLayout
();
TestLayout
offscreen
=
new
TestLayout
();
expect
(
onscreen
.
child
.
hasSize
,
isFalse
);
expect
(
onscreen
.
painted
,
isFalse
);
expect
(
offscreen
.
child
.
hasSize
,
isFalse
);
expect
(
offscreen
.
painted
,
isFalse
);
// Attach the offscreen to a custom render view and owner
RenderView
renderView
=
new
TestRenderView
();
PipelineOwner
pipelineOwner
=
new
PipelineOwner
();
renderView
.
attach
(
pipelineOwner
);
renderView
.
child
=
offscreen
.
root
;
renderView
.
scheduleInitialFrame
();
// Lay out the offscreen
pipelineOwner
.
flushLayout
();
expect
(
offscreen
.
child
.
hasSize
,
isTrue
);
expect
(
offscreen
.
painted
,
isFalse
);
// Make sure the onscreen didn't get laid out
expect
(
onscreen
.
child
.
hasSize
,
isFalse
);
expect
(
onscreen
.
painted
,
isFalse
);
// Now lay out the onscreen in the default binding
layout
(
onscreen
.
root
,
phase:
EnginePhase
.
layout
);
expect
(
onscreen
.
child
.
hasSize
,
isTrue
);
expect
(
onscreen
.
painted
,
isFalse
);
expect
(
onscreen
.
child
.
size
,
equals
(
const
Size
(
800.0
,
10.0
)));
});
}
packages/flutter/test/rendering/rendering_tester.dart
View file @
bb5a82a7
...
...
@@ -41,16 +41,16 @@ class TestRenderingFlutterBinding extends BindingBase with Scheduler, Services,
@override
void
beginFrame
()
{
RenderObject
.
flushLayout
();
pipelineOwner
.
flushLayout
();
if
(
phase
==
EnginePhase
.
layout
)
return
;
RenderObject
.
flushCompositingBits
();
pipelineOwner
.
flushCompositingBits
();
if
(
phase
==
EnginePhase
.
compositingBits
)
return
;
RenderObject
.
flushPaint
();
pipelineOwner
.
flushPaint
();
if
(
phase
==
EnginePhase
.
paint
)
return
;
render
er
.
render
View
.
compositeFrame
();
renderView
.
compositeFrame
();
}
}
...
...
packages/flutter_sprites/lib/src/sprite_box.dart
View file @
bb5a82a7
...
...
@@ -58,8 +58,8 @@ class SpriteBox extends RenderBox {
}
@override
void
attach
()
{
super
.
attach
();
void
attach
(
PipelineOwner
owner
)
{
super
.
attach
(
owner
);
_scheduleTick
();
}
...
...
packages/flutter_test/lib/src/widget_tester.dart
View file @
bb5a82a7
...
...
@@ -46,20 +46,20 @@ class _SteppedWidgetFlutterBinding extends WidgetFlutterBinding {
// Cloned from Renderer.beginFrame() but with early-exit semantics.
void
_beginFrame
()
{
assert
(
renderView
!=
null
);
RenderObject
.
flushLayout
();
pipelineOwner
.
flushLayout
();
if
(
phase
==
EnginePhase
.
layout
)
return
;
RenderObject
.
flushCompositingBits
();
pipelineOwner
.
flushCompositingBits
();
if
(
phase
==
EnginePhase
.
compositingBits
)
return
;
RenderObject
.
flushPaint
();
pipelineOwner
.
flushPaint
();
if
(
phase
==
EnginePhase
.
paint
)
return
;
renderView
.
compositeFrame
();
// this sends the bits to the GPU
if
(
phase
==
EnginePhase
.
composite
)
return
;
if
(
SemanticsNode
.
hasListeners
)
{
RenderObject
.
flushSemantics
();
pipelineOwner
.
flushSemantics
();
if
(
phase
==
EnginePhase
.
flushSemantics
)
return
;
SemanticsNode
.
sendSemanticsTree
();
...
...
packages/flutter_tools/lib/src/commands/analyze.dart
View file @
bb5a82a7
...
...
@@ -347,6 +347,7 @@ class AnalyzeCommand extends FlutterCommand {
new
RegExp
(
'^
\\
[(hint|error)
\\
] Unused import
\\
(
${mainFile.path}
,'
),
new
RegExp
(
r'^\[.+\] .+ \(.+/\.pub-cache/.+'
),
new
RegExp
(
'
\\
[warning
\\
] Missing concrete implementation of
\'
RenderObject
\\
.applyPaintTransform
\'
'
),
// https://github.com/dart-lang/sdk/issues/25232
new
RegExp
(
'
\\
[warning
\\
] Missing concrete implementation of
\'
AbstractNode
\\
.attach
\'
'
),
// https://github.com/dart-lang/sdk/issues/25232
new
RegExp
(
r'[0-9]+ (error|warning|hint|lint).+found\.'
),
new
RegExp
(
r'^$'
),
];
...
...
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